大数据展示需要用堆叠的柱状图,因为数量比较多,要求循环滚动显示,echart的堆叠柱状图满足不了,只能手写一个了。
<template>
<div class="chart_content all_model">
<div class="chart_box">
<div class="chart_title">
<span class="el-icon-caret-right"></span>
名称
</div>
<div class="chart_tip">
<span class="color1"></span>课程1
<span class="color2"></span>课程2
<span class="color3"></span>课程3
<span class="color4"></span>课程4
<span class="color5"></span>课程5
</div>
<div class="model_content">
<div class="model_row">
<vue-seamless-scroll :data="list" :class-option="defaultOption">
<ul class="model_row_ul">
<li v-for="(item,index) of list" :key="'row_'+index" class="the_row">
<el-tooltip placement="bottom">
<div slot="content">
<ul class="chart_tooltip">
<li>{{item.name}}</li>
<li><span class="color1"></span>{{item.count1}}</li>
<li><span class="color2"></span>{{item.count2}}</li>
<li><span class="color3"></span>{{item.count3}}</li>
<li><span class="color4"></span>{{item.count4}}</li>
<li><span class="color5"></span>{{item.count5}}</li>
</ul>
</div>
<div>
<p class="row_name">{{item.ClientName}}</p>
<ul class="my_bars">
<li :style="{width: item.percent1+'%'}" class="bar1">{{item.count1>0?item.count1:''}}</li>
<li :style="{width: item.percent2+'%'}" class="bar2">{{item.count2>0?item.count2:''}}</li>
<li :style="{width: item.percent3+'%'}" class="bar3">{{item.count3>0?item.count3:''}}</li>
<li :style="{width: item.percent4+'%'}" class="bar4">{{item.count4>0?item.count4:''}}</li>
<li :style="{width: item.percent5+'%'}" class="bar5">{{item.count5>0?item.count5:''}}</li>
</ul>
</div>
</el-tooltip>
<div class="row_index">
<p>{{index+1}}</p>
<p><img src="../../../assets/img/bd_index.png"></p>
</div>
</li>
</ul>
</vue-seamless-scroll>
</div>
</div>
<div class="model_content_x">
<!--底部坐标轴-->
<ul class="model_x">
<li v-for="(item,index) of numArr" :key="'x_'+index">
<span v-if="index===0" class="x_num_1">0</span>
<span class="x_num">{{item}}</span>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
import vueSeamlessScroll from 'vue-seamless-scroll';
export default {
name: "model",
components: {
vueSeamlessScroll
},
props:{
modelList:{
type:Array,
default:()=>{
return []
}
}
},
data() {
return {
list:[],
maxNum:10,
numArr:[],
}
},
created() {
},
methods:{
initData(list){
let theList=JSON.parse(JSON.stringify(list))
if(theList.length<=0) return;
//计算总和
theList.forEach(item=>{
item.total=(item.count1+item.count2+item.count3+item.count4+item.count5)
})
//找到最大的那个数
let max = theList[0].total,result='',resultNum=10;
theList.forEach(item => max = item.total > max ? item.total : max)
//取整,比如56,是2位数,转换成字符,取第一个,变成数字加1,十位数上就变成了6,再根据字符总长度-1补充0,再转换成数字,就是最接近最大值的整数
const str=max+''
result=Number(str.substring(0,1))+1
for (let i=0;i<str.length-1;i++){
result=result+'0'
}
resultNum=Number(result)
//获取最大的数值,最小是10
this.maxNum=resultNum<10?10:resultNum
//按最大的数值5等分,获取每个节点的数字
let n=this.maxNum/5,m=this.maxNum/n;
for (let l=1;l<=m;l++){
this.numArr.push(l*n)
}
//计算各个模块的百分比
theList.forEach(item=>{
item.percent1=(item.count1/this.maxNum*100)
item.percent2=(item.count2/this.maxNum*100)
item.percent3=(item.count3/this.maxNum*100)
item.percent4=(item.count4/this.maxNum*100)
item.percent5=(item.count5/this.maxNum*100)
})
this.list=JSON.parse(JSON.stringify(theList))
}
},
computed: {
defaultOption () {
return {
step: 0.2, // 数值越大速度滚动越快
limitMoveNum: 2, // 开始无缝滚动的数据量 this.dataList.length
hoverStop: true, // 是否开启鼠标悬停stop
direction: 1, // 0向下 1向上 2向左 3向右
openWatch: true, // 开启数据实时监控刷新dom
singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
waitTime: 1000 // 单步运动停止的时间(默认值1000ms)
}
}
},
watch:{
modelList:{
handler (newValue) {
this.initData(newValue)
},
deep: true,
immediate:true
}
}
}
</script>
vueSeamlessScroll最初的时候不滚动,也不报错,后发现父类position: absolute; 后又增加了个div才可以滚动
<style scoped rel="stylesheet/scss" lang="scss">
@import "./bigData.scss";
.all_model{
position: relative;
height: 600px;
width: 100%;
.chart_tip{
margin-top: 15px;
display: flex;
font-size: 12px;
color: #579AEC;
>span{
width: 9px;
height: 9px;
margin: 1px 3px 0 20px;
background-color: #7a90a9;
&:first-child{
margin-left: 0;
}
&.color1{
background-color: #EF476F;
}
&.color2{
background-color: #FFD166;
}
&.color3{
background-color: #06D6A0;
}
&.color4{
background-color: #A26FFF;
}
&.color5{
background-color: #36D2FF;
}
}
}
.model_content{
padding: 0 10px 0 15px;
position: relative;
width: 100%;
height: 480px;
margin-top: 25px;
overflow: hidden;
.model_row{
width: 100%;
height: 100%;
text-align: left;
position: absolute;
padding: 0 10px 0 0px;
left: 0;
top: 0px;
z-index: 10;
.model_row_ul{
width: 100%;
height: 100%;
margin-left: 35px;
.the_row{
position: relative;
width: 100%;
margin: 15px 0;
&:last-child{
margin-bottom: 0;
}
.row_name{
color: #579AEC;
margin-bottom: 3px;
}
.my_bars{
display: flex;
width: 100%;
height: 15px;
line-height: 15px;
font-size: 12px;
background-color: #083D7B;
>li{
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&.bar1{
background-color: rgb(152,66,118);
}
&.bar2{
background-color: rgb(155,179,126);
}
&.bar3{
background-color: rgb(12,140,150);
}
&.bar4{
background-color: rgb(83,88,186);
}
&.bar5{
background-color: rgb(32,134,187);
}
}
}
.row_index{
position: absolute;
height: 40px;
left: -34px;
top: 1px;
color: #3DF8FF;
text-align: center;
}
&:hover{
.my_bars{
>li{
&.bar1{
background-color: #EF476F;
}
&.bar2{
background-color: #FF9A0A;
}
&.bar3{
background-color: #06D6A0;
}
&.bar4{
background-color: #A26FFF;
}
&.bar5{
background-color: #36D2FF;
}
}
}
}
}
}
}
}
.model_content_x{
padding: 0 15px;
position: absolute;
width: 100%;
height: 510px;
bottom: -3px;
left: 0;
.model_x{
display: flex;
padding: 0 10px 0 35px;
width: 100%;
height: 105%;
>li{
position: relative;
height: 90%;
width: 20%;
border-right: 1px dashed rgb(50,86,156);
&:first-child{
border-left: 1px dashed rgb(50,86,156);
}
.x_num{
position: absolute;
display: inline-block;
width: 80px;
bottom: -20px;
right: 50%;
margin-right: -95px;
color: #579AEC;
text-align: center;
}
.x_num_1{
position: absolute;
color: #579AEC;
bottom: -20px;
left: -5px;
}
}
}
}
}
::v-deep .chart_tooltip{
font-size: 14px;
>li{
display: flex;
align-items: center;
margin-bottom: 5px;
&:last-child{
margin-bottom: 0;
}
>span{
display: inline-block;
width: 9px;
height: 9px;
margin-right: 4px;
&.color1{
background-color: #EF476F;
}
&.color2{
background-color: #FFD166;
}
&.color3{
background-color: #06D6A0;
}
&.color4{
background-color: #A26FFF;
}
&.color5{
background-color: #36D2FF;
}
}
}
}
</style>