文章目录
echarts各个场景遇到的问题
折线图-区域面积图 areaStyle
areaStyle: {
opacity: 0.8, // 透明度
color: {
/*折线-面积区域-颜色渐变*/
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: val.colorList[index], // 0% 处的颜色
},
{
offset: 1,
color: 'rgba(255,255,255,0.4)' // 100% 处的颜色
}
],
global: false // 缺省为 false
},
},
// stack:'Total', // 堆积。
/*面积图的时候,hover后,是否隐藏(置灰)其他线,只保留当前的自己内容*/
emphasis: {
focus: 'series', // hover的交互。
},
y轴只有整数
yAxis:
scale:true, // y坐标轴不从0开始
y轴不从0开始
yAxis:
minInterval: 1, // 不显示小数,只有整数
y轴数值不确定,有大有小,需要动态处理
/***
* 计算数值的最大值,根据最大值,设备grip的left,否则数值可能显示不全的!
* @type {number[]}
*/
let maxNumList = [1000] // 默认4位数的宽度。
// 找出各个系列中的max
option.series.forEach(v=>{
let maxNum = Math.max(...v.data)
maxNumList.push(maxNum)
})
// console.log('最大值list:',maxNumList)
// 找出max
let max = Math.max(...maxNumList)
let maxLength = (max+'').length
// 默认一个字站位12px
option.grid.left = 12*maxLength + ''
this.echartsIns.setOption(option, true)
折线-显示label
series-line. label
标线
// 插入一个标线
markLine: {
silent: false, // 图形是否不响应和触发鼠标事件:false true
label:{
show:true, //
position:'end', // 标签位置
distance:-20, // 标签与线之间的间距
// 标签内容格式器
formatter:(params)=>{
console.log('markLine-format:',params)
return params.name+ ':' + params.value
}
},
data: [
{ yAxis: 33, },
{
type:'average', // 平均值
name:'平均值a', //
},
{
type:'min', // 最小值
name:'最小值b', //
},
{
type:'max', // 最大值
name:'最大值c', //
},
]
},
legend的格式化和默认选中状态
// 图例组件。
legend: {
show: true, // true, false
formatter: (name) => {
// return `ks-${name}` // 添加前缀
// 自己处理文字
return echarts.format.truncateText(name, 40)
},
// 图例选择的模式,控制是否可以通过点击图例改变系列的显示状态。默认开启图例选择,可以设成 false 关闭。
selectedMode: true, // true,false 是否可以选择切换legend
selected: {
// key是data中的name字段
'人员': false,
'绩效': true,
},
},
x轴的lable超长处理
- 换行
format的时候,隔几个字就加一个‘\n’,换行处理了 - 旋转:旋转一定的度数
- 隔几个显示,
x轴的相关设置
xAxis: {
show: true, // false true
type: 'category', // 坐标轴类型。'value' 数值轴,适用于连续数据。'category' 类目轴. 'time' 时间轴.'log' 对数轴。
// 坐标轴 '轴线' 相关设置。
axisLine: {
show: true, // false,true
symbol: ['none', 'arrow'], // x轴是否有箭头
symbolSize: [10, 15], // 轴线两边的箭头的大小
lineStyle: {},
},
// 坐标轴'刻度'相关设置。
axisTick: {},
// 坐标轴刻度'标签'的相关设置。
axisLabel: {
show: true, // false,true
rotate: 25, // 旋转度数
color: (value) => {
console.log('x轴value:', value)
return value == '08:00' ? '#0e0e0e' : 'rgba(255,68,0,0.5)'
}
},
// 坐标轴在 grid 区域中的分隔线。(垂直坐标轴的线)
splitLine: {
show: true, // 坐标轴在 grid 区域中的分隔线。
interval: 0,
lineStyle: {
color: 'rgba(59,26,203,0.4)',
type:[4,4],// 'dotted'等
width:2,
},
},
// 类目数据,在类目轴(type: 'category')中有效。
data: val.xData,
// 坐标轴指示器配置项。(hover x轴的时候,选中区域或者line的效果)
axisPointer: {
// show:true,
type: 'line', // line shadow none
}
},
全选和反选
/**
* 接口入参:
* 1.有countFlag,默认优先(不需要startTime和endTime)
* 2.没有统计维度的时候,用startTime和endTime;后端做维度计算了;
* */
let params = {
// startTime: this.dateRange[0],
// endTime: this.dateRange[1],
// countFlag: 'd', // 统计维度(年-y,月-m,周-w,日-d)
}
if (this.dateType) {
if (this.dateType == 'day') {
params['countFlag'] = 'd'
} else if (this.dateType == 'week') {
params['countFlag'] = 'w'
} else if (this.dateType == 'month') {
params['countFlag'] = 'm'
} else if (this.dateType == 'year') {
params['countFlag'] = 'y'
} else if (this.dateType == 'hour') {
params['countFlag'] = 'h'
} else if (this.dateType == 'minute') {
params['countFlag'] = 'M'
}
} else {
// 分钟级别的怎么办?
// 小于24小时,用小时;小于30天,用天;小于一年,用月;大于一年,用年;
// console.log('时间差:',moment(this.dateRange[1]).diff(this.dateRange[0]))
/*input选择日期范围的时候:不需要前端做时间差的计算了,后端已经做了*/
params['startTime'] = this.dateRange[0]
params['endTime'] = this.dateRange[1]
}
// 产品、设备、消息是不同的 接口
let serviceName = queryProductIncrementCount
if (this.cardType == 'product') {
serviceName = queryProductIncrementCount
} else if (this.cardType == 'device') {
serviceName = queryDeviceIncrementCount
} else if (this.cardType == 'message') {
serviceName = queryDeviceMsgIncrementCount
}
this.isEchartsLoading = true
let res = await serviceName(params).catch(() => {
this.isEchartsLoading = false
})
this.isEchartsLoading = false
console.log('echarts-产品res:', res)
/*
* 目前看返回是一样的,实际上有不一样的,需要单独处理返回数据的!
* 设备肯定与其他的不同处理!
* */
if (this.cardType == 'product') {
let xData = []
let yData = []
res && res.data && res.data.bizDataList.forEach(v => {
xData.push(v.itemKey)
yData.push(v.itemValue)
})
this.echartsData.xAxis.data = xData
this.echartsData.title.text = '累计创建产品数(个)'
this.echartsData.legend = { show: false, }
this.echartsData.series = [
{
name: '产品数量',
data: yData,
type: 'line',
}
]
} else if (this.cardType == 'device') {
let xData = []
let yData = []
res && res.data && res.data.deviceIncrementList.forEach((v, k) => {
// 多个数据
let arr = []
v.data.bizDataList.forEach((val, ind) => {
// 处理x轴
if (k == 0) {
xData.push(val.itemKey)
}
// 处理y轴
arr.push(val.itemValue)
})
// 多个数据
yData.push({
data: arr,
name: PRODUCT_TYPE_OBJ[v.deviceType] || v.deviceType,
type: 'line',
// stack: 'Total',
// areaStyle: {
// opacity: 0.4,
// },
// emphasis: {
// focus: 'series'
// },
})
})
/*设备总量统计*/
let totalArr = []
res && res.data && res.data.totalDeviceIncrementList.forEach(v => {
totalArr.push(v.itemValue)
})
yData.push({
data: totalArr,
name: '设备总量',
type: 'line',
// areaStyle:{
//
// },
})
this.echartsData.xAxis.data = xData
this.echartsData.title.text = '累计创建设备数(个)'
this.echartsData.legend = {
show: true,
selector: [
{ type: 'all', title: '全选', },
{ type: 'inverse', title: '反选', },
],
selectorLabel: {
verticalAlign: 'middle',
// padding:[0,0,4,0],
},
width: '90%',
}
/*this.echartsData.series = [
{
name: '子设备',
data: yData,
type: 'line',
stack: 'Total',
areaStyle: {
opacity: 0.4,
},
emphasis: {
focus: 'series'
},
},
]*/
this.echartsData.series = yData
} else if (this.cardType == 'message') {
let xData = []
let yData = []
res && res.data && res.data.bizDataList.forEach(v => {
xData.push(v.itemKey)
yData.push(v.itemValue)
})
this.echartsData.xAxis.data = xData
this.echartsData.title.text = '设备消息数(条)' // 万
this.echartsData.legend = { show: false, }
this.echartsData.series = [
{
name: '消息数量',
data: yData,
type: 'line',
}
]
}
<template>
<div class="basic-line-echarts" :id="id"
:class="className"
:style="{width:width,height:height,}">
</div>
</template>
<script>
import * as echarts from 'echarts'
import echartsResize from '@mixin/echartsResize'
export default {
name: 'BasicLineEcharts',
components: {},
mixins:[echartsResize],
data () {
return {
echartsIns: null,
}
},
props: {
id: { type: String, default: 'basicLineEcharts', },
className: { type: String, default: 'basicLineEcharts', },
width: { type: String, default: '100%', },
height: { type: String, default: '100%', },
echartsData: {
type: Object, default () {
return {}
}
},
},
computed: {},
methods: {
/**
* 实例化echarts
*/
initEcharts () {
// console.log('echarts-dom元素this.$el:', this.$el)
this.echartsIns = echarts.init(this.$el)
this.changeEcharts(this.echartsData)
},
/***
* 初始化echarts
*/
changeEcharts (echartsData = {}) {
// console.log('echarts的数据对象:', echartsData)
// 处理series:
let option = {
// 标题组件,包含主标题和副标题。
title: {
show: true, // 是否显示标题组件。
text: '', // 主标题文本,支持使用 \n 换行。
textStyle: {
color: '#646566',
fontWeight: 400,// 'bolder'
fontSize: 12,
lineHeight: 20,
},
left: 15, // title默认有padding:5。
},
// 画图的区域(不包括x轴和y轴的刻度和数字部分)
grid: {
// show:true,
left: '40',
top: '40',
right: '20',
bottom: '40',
// backgroundColor:'rgba(255,68,0,0.1)', // 需要设置show才显示bgc
// grid 区域是否包含坐标轴的刻度标签。
// containLabel:true, // false true
},
xAxis: {
type: 'category', // 坐标轴类型。'value' 数值轴,适用于连续数据。'category' 类目轴. 'time' 时间轴.'log' 对数轴。
// 坐标轴 '轴线' 相关设置。
axisLine: {
show: true, // false,true
lineStyle: {
color: '#C8C9CC', // #333
},
},
// 坐标轴'刻度'相关设置。
axisTick: {
show: true, // false,true
alignWithLabel: true,
length: 4, // 坐标轴刻度的长度。
// 刻度线的样式设置。
lineStyle: {
color: '#C8C9CC', // #333
},
},
// 坐标轴刻度'标签'的相关设置。
axisLabel: {
color: '#646566', // #333
},
},
yAxis: {
type: 'value',
// scale:true, // y坐标轴不从0开始
// minInterval: 1, // 不显示小数,只有整数。
// 坐标轴 '轴线' 相关设置。
axisLine: {
show: false, // false,true
// lineStyle:{
// color:'#C8C9CC', // #333
// },
},
// 坐标轴'刻度'相关设置。
axisTick: {
show: false, // false,true
length: 4, // 坐标轴刻度的长度。
// 刻度线的样式设置。
// lineStyle: {
// color:'#C8C9CC', // #333
// },
},
// 坐标轴刻度'标签'的相关设置。
axisLabel: {
color: '#646566', // #333
},
// 坐标轴在 grid 区域中的分隔线。(垂直坐标轴的线)
splitLine: {
show: true, // 坐标轴在 grid 区域中的分隔线。
lineStyle: {
color: '#DCDDE0',
// type:'dashed',
type: [2, 2],
},
},
},
tooltip: {
trigger: 'axis', // 多个line,显示一个tooltip
// hover上后的效果
axisPointer: {
type: 'line', // 垂直x轴的;或者cross:交叉x和y轴的;
lineStyle: {
color: '#C8C9CC', //#555
type: 'solid',
},
},
/*格式化tooltip*/
/*formatter:(params)=>{
console.log(params)
let param = params[0]
// return param.seriesName
return param.marker +" " + param.seriesName +"<br>"
+" "+param.name+":"+ param.value + "<br>";
},*/
},
series: echartsData.series,
color: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'],
// legend:{show:false,},
}
// 颜色处理:
if (echartsData.color) {
option.color.unshift(...echartsData.color)
}
if (echartsData.legend){
option.legend = { ...echartsData.legend }
}
/*自己的配置,添加到options中*/
option.title = { ...option.title, ...echartsData.title, }
option.xAxis = { ...option.xAxis, ...echartsData.xAxis, }
option.grid = { ...option.grid, ...echartsData.grid, }
console.log('echarts的配置项内容option:', option)
/***
* 计算数值的最大值,根据最大值,设备grip的left,否则数值可能显示不全的!
* @type {number[]}
*/
let maxNumList = [1000]
option.series.forEach(v=>{
let maxNum = Math.max(...v.data)
maxNumList.push(maxNum)
})
// console.log('最大值list:',maxNumList)
let max = Math.max(...maxNumList)
let maxLength = (max+'').length
option.grid.left = 12*maxLength + ''
/*设置option,绘制echarts*/
this.echartsIns.setOption(option, true)
// this.echartsIns.showLoading()
this.echartsIns.on('legendselectchanged',(params)=>{
console.log('点击legend changeLegend:',params)
})
this.echartsIns.on('legendselectall',(params)=>{
console.log('全选 legendselectall:',params)
})
this.echartsIns.on('legendunselected',(params)=>{
console.log('置灰 legendunselected:',params)
})
this.echartsIns.on('legendselected',(params)=>{
console.log('选中 legendselected :',params)
})
},
},
created () {
},
mounted () {
this.initEcharts()
},
watch: {
/*监听数据变化,然后绘制echarts*/
echartsData: {
handler(newVal){
this.changeEcharts(newVal)
},
deep:true,
},
},
}
</script>
<style scoped lang='scss'>
</style>
import { debounce } from '@utils/utils'
export default {
data(){
return {
_handleResize:null,
}
},
methods:{
addListener(){
this._handleResize = debounce(()=>{
// console.log('mixin的this:',this) // 使用mixins的组件本身!
// console.log('屏幕的w screen.width:',screen.width)
this.echartsIns&&this.echartsIns.resize()
},100)
window.addEventListener('resize',this._handleResize)
},
},
mounted(){
this.addListener()
},
beforeDestroy () {
if(this.echartsIns){
window.removeEventListener('resize',this._handleResize)
}
},
}