根据一些实用、不难但是繁琐的功能,推出一个这个系列,方便大家以后直接拿来就用。
缘由:
最新有老师看见其他网站有仿github活跃图的效果,让我安排一下。
去github仔细看了看,以一个想法是看看echarts有没有类似的,找了一会发现有个类似的,但是修改成本较大,果断造轮子。
效果图:
思路:
1.先排除坐标说明,绘制最里面的每个小格子。
第一个格子的时间:上一年今天如果不是周一,那么推到下一个周一。
最后一个格子的时间:今天。
格子的数量:最后一个格子时间 - 第一个格子时间 。
最后一个列的个数:今天的星期数 或 格子总数量除以7取余。
格子的颜色:格子是用for循环变量的数组数据,设置每个格子data时候,带上提交次数属性,然后写个根据数量获取不同颜色的方法。
鼠标移入的内容:组件采用的iview的tooltip。根据项目集成的ui库可更改,或者手写一个也不难。
2.绘制x,y轴坐标值。
y坐标代表星期数,比较简单,直接添加格子容器节点的上面就行。
x坐标代表月份, 并非每列都有月份,只会在当前月份的第一列显示月份。
月份第一个列判断依据:每个格子我都赋予了具体的日期,判断前一列是否有不相同月份的日期,如果有不同的日期设置一个变量为true,如果没有重新设置成false,然后根据这个变量来决定本列是不是月份第一列。
3.绘制legend。
位置使用flex布局就行,不做过多解释。
左侧的slider用的iview。
代码:
<template>
<div class="submission-chart">
<div class="calendar">
<div class="weeks">
<div class="week">周二</div>
<div class="week">周四</div>
<div class="week">周六</div>
</div>
<div class="column" v-for="(columnData, columnIndex) in dateData" :key="columnIndex">
<div class="title">{{columnData.title}}</div>
<div
class="date-wrapper"
v-for="(dateData, dateIndex) in columnData.data"
:key="dateIndex"
:style="`background:${getColor(dateData.number)};`"
>
<Tooltip placement="top" :delay="300" :content="`${dateData.date}:${dateData.number}次通过`">
<div class="date"></div>
</Tooltip>
</div>
</div>
</div>
<div class="operation">
<div class="slider">
<div class="slider-desc">0</div>
<div style="width:120px;">
<Slider :value="sliderValue" :max="12" range :tip-format="sliderFormat" @on-change="sliderChange"></Slider>
</div>
<div class="slider-desc">12+</div>
</div>
<div class="legend">
<div class="level-desc">少</div>
<div class="level level-1"></div>
<div class="level level-2"></div>
<div class="level level-3"></div>
<div class="level level-4"></div>
<div class="level level-5"></div>
<div class="level-desc">多</div>
</div>
</div>
</div>
</template>
<script>
import moment from 'moment'
export default {
name: 'submission-chart',
data () {
return {
dateData: [],
submissionRecord: {},
sliderValue: [0, 12]
}
},
props: {
profile: {
default: {},
type: Object
}
},
mounted () {
this.formatProblemData()
this.init()
},
methods: {
init () {
// 上一年信息
let prevYear = moment().format('YYYY') - 1
let prevTodayFormatStr = prevYear + '-' + moment().format('MM-DD')
let prevToday = moment(prevTodayFormatStr).format('YYYY-MM-DD')
// 上年今日的是星期几
let prevTodayWeekNum = moment(prevToday).weekday() || 7
// 初始日期(上年临近的星期一)
let firstMondayDate = prevTodayWeekNum > 1 ? moment(prevToday).add(8 - prevTodayWeekNum, 'da{
height: 11px;
background: #EBEDF0;
margin-bottom: 3px;
.date {
width: 11px;
height: 11px;
:hover {
width: 13px;
height: 13px;
}
}
}
}
}
.operation {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
.slider {
display: flex;
justify-content: center;
align-items: center;
width: 200px;
.slider-desc {
width: 11px;
margin: 0 8px;
}
}
.legend {
display: flex;
justify-content:center;
align-items: center;
.level-desc {
margin-right: 6px;
margin-left: 3px;
}
.level {
margin-right: 3px;
width: 11px;
height: 11px;
}
.level-1 {
background: #EBEDF0;
}
.level-2 {
background: #C6E48B;
}
.level-3 {
background: #7BC96F;
}
.level-4 {
background: #239A3B;
}
.level-5 {
background: #196127;
}
}
}
}
</style>
使用:
<submission-chart :profile="profile"/>
|