效果图如下
如示例图所展示的效果是每个文件类型所对应的热词被搜索了多少次;
实现方式
- 需要用到echarts气泡图的配置
<div ref="chart" class="charts-box" />
var option={
legend: {
// right: '10%',
// top: '3%',
data: []
},
grid: {
left: '8%',
top: '10%'
},
xAxis: {
type: 'category',
splitLine: {
interval: 0,
lineStyle: {
type: 'dashed'
}
},
interval: 0,
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#DCDFE6',
//这里是为了突出显示加上的
//横轴信息全部显示
}
},
axisLabel: {
fontWeight: 400,
fontFamily: 'Microsoft YaHei',
fontSize: 18,
color: '#303133',
showMinLabel: true,
showMaxLabel: true,
align: 'center',
interval: 0,//使x轴文字显示全
},
// scale: false,
data: []
},
// visualMap: {
// show: false,
// inRange: {
// symbolSize: [20, 50]
// }
// },
yAxis: {
type: 'category',
axisTick: {
show: false
},
interval: 0,
splitLine: {
show: true,
lineStyle: {
type: 'dashed'
}
},
axisLine: {
lineStyle: {
color: '#DCDFE6',
//这里是为了突出显示加上的
//横轴信息全部显示
}
},
axisLabel: {
fontWeight: 400,
fontFamily: 'Microsoft YaHei',
fontSize: 18,
color: '#303133',
showMinLabel: true,
showMaxLabel: true,
// align: 'left',
interval: 0,//使x轴文字显示全
},
data: [],
scale: false
},
series: {
type: 'scatter',
// data: []
}
}
mounted() {
this.getHotWordsList()
this.initChart();
window.addEventListener("resize", this.resizeChart);
},
methods: {
resizeChart() {
if (this.chart) {
this.chart.resize();
}
},
initChart() {
// debugger
this.chart = this.$echarts.init(this.$refs.chart);
this.chart.setOption(this.option);
},
getSeariesData(val) {
//先说下val的数据格式[{groupName:"",name:"",value:""},{groupName:"",name:"",value:""}]需要遍历data赋值的是索引。
//val也可以是这种数据格式;val=[
// [0, '江西', 2], // 意思是此点位于 xAxis: '星期一', yAxis: '江西',最后一位索引代表值。
// [3, '湖南', 1], // 意思是此点位于 xAxis: '星期四', yAxis: '湖南'。
// [2, '河北', 2], // 意思是此点位于 xAxis: '星期三', yAxis: '河北'。
// [3, '甘肃', 5]
]
//进行遍历此时data赋值其中一位索引值,这种配置不了图例
this.option.series = val.map((d, i) => {
return {
type: 'scatter',
name: d.name,//用来配置图例的也可以不要,需要跟lenged的data配置的名称一样
label: {
show: true,
color:'#fff',
formatter: function (params) {
return val[params.seriesIndex].value;//气泡值
}
},
symbolSize: d.value * 2,
data: [[
this.option.xAxis.data.indexOf(d.groupName),//x轴data的索引,因为数据格式是这种的,所以x轴都是去重,y轴也是
this.option.yAxis.data.indexOf(d.name)//y轴data的索引
]],
itemStyle: {
color: this.colors[data[i]]//给每一种气泡设置的颜色值
}
// data: [
// [
// xData.indexOf(d.tech),
// yData.indexOf(d.business)
// ]
// ]
}
})
},
}
没有2了就这样吧,给series赋值,xy轴赋值就ok了
赋上完整的代码
<template>
<div class="container">
<div class="file-type">
<span class="file-type-title">文件类型</span>
<ul class="file-type-classify">
<li :class="checkedAllFileType ? 'label-all active ' : 'label-all'" @click="checkedAllFile()">全部</li>
<li v-for="(item) in currentfileType" :key="item.key" :label="item.groupName" @click="checkedFile(item)" :class="item.checked ? 'label-all active ' : 'label-all'">{{item.groupName}}({{item.value}})</li>
</ul>
</div>
<div v-if="flag" ref="chart" class="charts-box" />
<div v-else class="noData">
<img src="../../../assets/no-data.png" alt="">
</div>
</div>
</template>
<script>
var SDATA = [
// xAxis yAxis
// [0, '江西', 2], // 意思是此点位于 xAxis: '星期一', yAxis: '江西',最后一位索引代表值。
// [3, '湖南', 1], // 意思是此点位于 xAxis: '星期四', yAxis: '湖南'。
// [2, '河北', 2], // 意思是此点位于 xAxis: '星期三', yAxis: '河北'。
// [3, '甘肃', 5]
]
// var xData = ['星期一', '星期二',‘星期三’,‘星期四’];
// var yData = ['江西', '湖南', '河北', '甘肃']
// var data = [1,2,3,4,5,6,7,8,9,10]
import { getHotWordsList } from "@/api/fileRetrieval/fileRetrieval"
export default {
name: "fileTrendBox",
data() {
return {
chart: null,
flag:true,
currentfileType: [
],
option: {
//气泡图的色值
color:['#FF9514', '#3F9BF6', '#33A07B','#A776E4','#FFD491','#B3D8FF','#F78989','#FBC4C4','#A6D8CA','#FFD800','#8BA6FF','#DC4640'],
legend: {
// right: '10%',
// top: '3%',
//气泡图图例为检索热词
data: []
},
grid: {
left: '8%',
top: '10%',
height:'75%',
},
xAxis: {
type: 'category',
splitLine: {
interval: 0,
lineStyle: {
type: 'dashed'
}
},
interval: 0,
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#DCDFE6',
//这里是为了突出显示加上的
//横轴信息全部显示
}
},
axisLabel: {
fontWeight: 400,
fontFamily: 'Microsoft YaHei',
fontSize: 18,
color: '#303133',
margin: 20,
showMinLabel: true,
showMaxLabel: true,
align: 'left',
interval: 0,//使x轴文字显示全
rotate:-30,
},
// scale: false,
data: []
},
yAxis: {
type: 'category',
axisTick: {
show: false
},
interval: 0,
splitLine: {
show: true,
lineStyle: {
type: 'dashed'
}
},
axisLine: {
lineStyle: {
color: '#DCDFE6',
//这里是为了突出显示加上的
//横轴信息全部显示
}
},
axisLabel: {
fontWeight: 400,
fontFamily: 'Microsoft YaHei',
fontSize: 18,
color: '#303133',
showMinLabel: true,
showMaxLabel: true,
// align: 'left',
interval: 0,//使x轴文字显示全
margin:20,
//Y轴文字过长时换行展示
formatter: function (params) {
var newParamsName = "";
var paramsNameNumber = params.length;
var provideNumber = 6; //一行显示几个字
var rowNumber = Math.ceil(paramsNameNumber / provideNumber);
if (paramsNameNumber > provideNumber) {
for (var p = 0; p < rowNumber; p++) {
var tempStr = "";
var start = p * provideNumber;
var end = start + provideNumber;
if (p == rowNumber - 1) {
tempStr = params.substring(start, paramsNameNumber);
} else {
tempStr = params.substring(start, end) + "\n";
}
newParamsName += tempStr;
}
} else {
newParamsName = params;
}
return newParamsName
},
},
data: [],
scale: false
},
series: {
type: 'scatter',
// data: []
}
// SDATA.map((d, i) => {
// return {
// type: 'scatter',
// label: {
// show: true,
// // formatter: function (params) {
// // return data[params.seriesIndex].num;
// // }
// },
// symbolSize:d[2]*5,
// data:d,
// itemStyle:{
// color:this.getColor(d[0])
// }
// // data: [
// // [
// // xData.indexOf(d.tech),
// // yData.indexOf(d.business)
// // ]
// // ]
// }
// })
},
checkedAllFileType: true,
checkedFileType: '',
analysData: [],
};
},
watch: {
opthions() {
this.initChart();
},
currentfileType: {
handler(val) {
let arr = JSON.parse(JSON.stringify(val))
let selectArr = (arr.filter((value, index, array) => {
return value.checked
})).map(item => {
return item.key
})
if (selectArr.length) {
let seletData = this.analysData.filter(item => {
return selectArr.indexOf(item.key) > -1
})
// this.getXYData(seletData)
this.getSeariesData(seletData)
// console.log(this.option.series.data,'series')
//处理seariesdata
this.chart.clear()
this.chart.setOption(this.option);
} else {
this.checkedAllFile()
}
},
deep: true
},
checkedAllFileType(val) {
if(val) {
this.getSeariesData(this.analysData)
this.chart.clear()
this.chart.setOption(this.option);
}
}
},
mounted() {
this.getHotWordsList()
this.initChart();
window.addEventListener("resize", this.resizeChart);
},
computed: {
fileForm() {
return JSON.parse(this.$store.state.fileRetrieval.fileForm).textForm.expression
},
fileType() {
return JSON.parse(this.$store.state.fileRetrieval.fileData)['data']['FILE_TYPE']
},
},
beforeDestroy() {
window.removeEventListener("resize", this.resizeChart);
},
methods: {
resizeChart() {
if (this.chart) {
this.chart.resize();
}
},
initChart() {
// debugger
this.chart = this.$echarts.init(this.$refs.chart);
this.chart.setOption(this.option);
},
checkedFile(item) {
this.checkedAllFileType = false
item.checked = !item.checked
},
checkedAllFile() {
this.checkedAllFileType = true;
this.currentfileType.forEach(item => {
item.checked = false
})
},
getHotWordsList() {
// let param = this.fileForm
getHotWordsList()
.then((res) => {
if(!res.data.length) {
this.flag = false
}else {
this.flag = true
}
let fileType = this.fileType
let fileArr = fileType.map(item => {
return item.key
})
//转换文件类型名添加key
res.data = res.data.map((value, index) => {
if (fileArr.indexOf(value.groupName) !== -1) {
return {
groupName: fileType[fileArr.indexOf(value.groupName)].name,
key: fileType[fileArr.indexOf(value.groupName)].key,
name: value.name,
value: value.count
}
} else {
return {
groupName: value.groupName,
key: value.groupName,
name: value.name,
value: value.count
}
}
})
this.analysData = res.data
//遍历文件类型
this.getCurrentfileType()
//x轴y轴数据
this.getXYData(this.analysData)
//获取searies的数据
this.getSeariesData(this.analysData)
if(this.flag) {
//清除画布,防止缓存
this.chart.clear()
//处理seariesdata
this.chart.setOption(this.option);
}
})
.catch((error) => {
console.log(error)
})
},
getCurrentfileType() {
let arr = [];
//遍历文件类型计算数量
this.analysData.forEach((item, index) => {
if (arr.indexOf(item.key) === -1) {
arr.push(item.key);
this.currentfileType.push({
name: item.name,
value: item.value,
key: item.key,
checked: false,
groupName: item.groupName
})
} else {
this.currentfileType[arr.indexOf(item.key)].value = this.currentfileType[arr.indexOf(item.key)].value + item.value;
}
})
},
//XY轴的数据
getXYData(val) {
this.option.xAxis.data = this.currentfileType.map(item => {
return item.groupName
})
this.option.yAxis.data = (Array.from(new Set(val.map(item => {
return item.name
})))).reverse()
this.option.legend.data = this.option.yAxis.data
},
getSeariesData(val) {
// let arr = []
// val.forEach((item) => {
// let i = this.option.xAxis.data.indexOf(item.groupName)
// console.log(i, 'i')
// arr.push([i,item.name,item.value])
// })
// console.log(val,'val')
const size = {
minSize: 5,
maxSize: 50,
};
const maxCount = this.analysData.reduce((max, item) => Math.max(max, item.value), 0);
this.option.series = val.map((d, i) => {
return {
type: 'scatter',
name: d.name,
label: {
show: true,
color:'#fff',
formatter: function (params) {
return val[params.seriesIndex].value;
}
},
symbolSize: d.value ? (Math.round((size.maxSize - size.minSize) * d.value / maxCount) + size.minSize) : 0,
// symbolSize: d.value < 10&&d.value ? 15 : (d.value>90?90:d.value),
// symbolSize: 100,
data: [[
this.option.xAxis.data.indexOf(d.groupName),
this.option.yAxis.data.indexOf(d.name)
]],
// itemStyle: {
// color: this.option.color
// }
// data: [
// [
// xData.indexOf(d.tech),
// yData.indexOf(d.business)
// ]
// ]
}
})
},
},
};
</script>
<style lang="scss" scoped>
.container {
width: 100%;
height: 100%;
.file-type {
padding-top: 10px;
// padding-bottom: 10px;
width: 100%;
// height: 100px;
border-bottom: 1px solid #dcdfe6;
display: flex;
align-items: center;
// line-height: 110px;
.file-type-title {
font-family: Microsoft YaHei;
font-weight: 400;
font-size: 18px;
color: #606266;
margin-right: 20px;
margin-bottom: 10px;
}
.file-type-classify {
font-size: 18px;
color: #303133;
font-family: Microsoft YaHei;
flex: 1;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: wrap;
.label-all {
margin-bottom: 10px;
margin-left: 10px;
height: 40px;
font-weight: 400;
// line-height: 40px;
padding: 8px 15px;
cursor: default;
border-radius: 4px;
// &:hover {
// background: #ECF5FF;
// }
}
}
}
.charts-box {
width: 100%;
height: 800px;
// padding-bottom: 145px;
margin-top: 20px;
}
.noData {
width: 100%;
height: 600px;
// height: 100%;
position: relative;
// text-align: center;
// line-height: 50%;
// margin: 119px auto;
// background: url("../../../assets/no-data.png") no-repeat center center;
// background-size: contain;
color: #909399;
box-sizing: border-box;
img {
width: 250px;
height: 250px;
position: absolute;
left: 0;
bottom: 0;
right: 0;
top: 0;
margin: auto;
}
}
.active {
background: #ecf5ff;
color: #1082f4;
}
}
</style>