前言
前两天下发一个需求,需要实现一个月统计图,但是只显示最近周。思来想去找到了Echats
,但是具体跟UI设计差别过大,数据也不好整理。鼓捣了一早上之后选择放弃了。
其实Echats
也蛮好的,提供了多样化的数据图表,示例中涵盖各行各业。
实现
设计图如下,实现要求是当日加粗实体显示,其他模糊化,但可以选中查看。
HTML结构
结构规划比较简单,整体+容器+项目(头部/内容/底部),内容分有背景条和柱形条,就目前背景还没有去实现,主要点就是柱形条的高度变化和整体高度之间的处理。
<div class="zin-chat">
<div class="zin-chat-container">
<!-- 柱形 -->
<div class="zin-chat-item" :class="{ today: index === today }"
@click="today = index"
v-for="(item, index) in monthCompleted" :key="index">
<div class="zin-item-header">{{ index === 6 ? '今天' : item.date }}</div>
<div class="zin-item-body">
<div class="zin-item-body__bg"></div>
<!-- 动态高度计算(height/max) * item.score -->
<div class="zin-item-body__bar" :style="{height: barH(item.score) + 'px'}" >
<div class="zin-item-body__bar-text">{{ item.score }}分</div>
</div>
</div>
<div class="zin-item-footer"></div>
</div>
</div>
</div>
JS 操作处理
data() {
let monthData = [];
for (let i = 0; i < 7; i++) {
monthData.push({
date: '01.0' + (i+1),
score: Math.ceil(Math.random() * 280)
})
}
return {
monthCompleted: monthData,
today: 6
}
},
computed: {
barMaxHeight() {
// 取得数据最大值
let vm = this;
let maxHeight = 280;
maxHeight = vm.monthCompleted.reduce((prev, next) => {
// 上一个做直接数据
if(Object.prototype.toString.call(prev) === '[object Object]') {
prev = parseInt(prev.score);
}
// 大于值
if(prev > parseInt(next.score)) {
return prev;
} else return next.score;
})
return maxHeight;
}
},
methods: {
barH(score) {
let vm = this;
// 动态高度计算(height/max) * item
let height = 200/ vm.barMaxHeight * score;
// 底值处理
return height === 0 ? 1 : height;
}
}
CSS样式
// less
.zin-chat {
padding: 12px;
text-align: center;
.zin-chat-container {
position: relative;
display: flex;
align-items: baseline;
justify-content: space-between;
.zin-chat-item {
position: relative;
padding: 5px 5px 0;
border-radius: 3px;
min-width: 38px;
font-size: 12px;
color: #666666;
opacity: 0.6;
&.today {
background: #FAF0F1;
color: #E94B3C;
font-weight: 700;
opacity: 1;
}
.zin-item-header {
margin: 10px 0;
font-size: 12px;
text-align: center;
background: transparent;
}
.zin-item-body {
position: relative;
margin: 0 auto;
&__bg {
height: 220px;
border-radius: 3px;
}
&__bar {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 180px;
background: linear-gradient(to top, #E88744, #E85F3F, #E94B3C);
border-radius: 3px;
&-text {
position: absolute;
top: -20px;
left: 0;
right: 0;
font-size: 12px;
text-align: center;
}
}
}
}
}
}
结果
实现简单柱形图,可选中单条柱形
附加
如果要实现多条数据可以scroll实现多天
.zin-chat-container {
...
overflow: hidden;
overflow-x: scroll;
}