Echarts
封装echarts组件
<!-- 自适应布局放大缩小 -->
<template>
<div class="echart-con" :id="echartId" v-if="!showEmpty"></div>
<OccupyMap description="暂无数据..." v-else></OccupyMap>
</template>
<script>
import * as echarts from 'echarts'
import { extension } from '@/utils/methods'
export default {
props: {
option: {
type: Object,
default: () => {},
},
config: {
type: String,
default: () => 'svg',
},
showEmpty: {
type: Boolean,
default: () => false,
},
textToop: {
type: String,
default: () => '',
},
},
data() {
return {
echartId: 'myChart-' + Math.random() * 10,
mychart: null,
}
},
methods: {
initEchart() {
let { mychart } = this
if (mychart !== null && mychart !== '' && mychart !== undefined) {
mychart.dispose()
}
let chartDom = document.getElementById(this.echartId)
this.mychart = echarts.init(chartDom, null, {
renderer: 'canvas', // 设置渲染方式为 SVG
...this.config,
})
this.mychart.setOption(this.option, { lazyMode: true })
if (this.textToop) {
extension(this.mychart, this.textToop)
}
this.$emit('getChart', this.mychart)
setTimeout(() => {
this.mychart && this.mychart.resize()
}, 300)
},
debounce(fn, delay = 500) {
let timer = null
return function () {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
},
addResize() {
this.mychart && this.mychart.resize()
},
},
watch: {
option: {
handler: function () {
this.$nextTick(() => {
this.initEchart()
})
},
deep: true,
},
fold() {
this.$nextTick(() => {
this.mychart && this.mychart.resize()
})
},
showEmpty() {},
},
computed: {
fold() {
return this.$store.getters.getFold
},
},
mounted() {
// 提示框中的点击事件
function getDetails(data) {
window.$ehl.bus.emit('chartTotable', data)
//获取到点击查看的提示框的值
}
window.getDetails = getDetails
window.addEventListener('resize', this.debounce(this.addResize), false)
},
beforeMount() {
window.removeEventListener('resize', this.debounce(this.addResize), false)
},
}
</script>
<style lang="less" scoped>
.echart-con {
width: 100%;
height: 100%;
}
</style>
组件使用
<template>
<div class="earlyWarning-container">
<div class="chart_con" v-ehlLoading="isLoading1">
<div class="module-title">
<img :src="TitleIcon" alt="" />行为分布情况
</div>
<comEchartV1 :option="Option1" :showEmpty="showEmpty1" />
</div>
<div class="chart_con" v-ehlLoading="isLoading2">
<div class="module-title">
<img :src="TitleIcon" alt="" />地点分布情况
</div>
<comEchartV1 :option="Option2" :showEmpty="showEmpty2" />
</div>
<div class="chart_con" v-ehlLoading="isLoading3">
<div class="module-title">
<img :src="TitleIcon" alt="" />车辆分布情况
</div>
<comEchartV1 :option="Option3" :showEmpty="showEmpty3" />
</div>
<div class="chart_con" v-ehlLoading="isLoading4">
<div class="module-title">
<img :src="TitleIcon" alt="" />时段分布情况
</div>
<comEchartV1 :option="Option4" :showEmpty="showEmpty4" />
</div>
</div>
</template>
<script>
import * as echarts from 'echarts'
// import moment from 'moment'
// import { Input } from 'element-ui'
import TitleIcon from '@/views/sub_title_icon.png'
// import { illegalHighChartList } from './config.js'
import {
postillegalAnalysisillegalAnalysisBehavior,
postillegalAnalysisillegalAnalysisPlace,
postillegalAnalysisillegalAnalysisVehicle,
postillegalAnalysisillegalAnalysisTime,
getalarmRulequeryRulesByAlarmCode,
} from '@/utils/ajaxApi.js'
// import { extension } from '@/utils/methods'
import comEchartV1 from '@/common/echarts/comEchartV1.vue'
export default {
data() {
return {
TitleIcon,
isLoading1: false,
isLoading2: false,
isLoading3: false,
isLoading4: false,
Option1: {},
Option2: {},
Option3: {},
Option4: {},
showEmpty1: false,
showEmpty2: false,
showEmpty3: false,
showEmpty4: false,
BehaviorAlarmValue: 0,
PlaceAlarmValue: 0,
CarAlarmValue: 0,
BehaviorEchartData: [],
placeEchartData: [],
carEchartData: [],
TimeEchartData: [],
}
},
components: {
comEchartV1,
},
props: {
queryForm: {
type: Object,
default: () => {},
},
analysisHighIncidenceRules: {
type: Object,
default: () => {},
},
},
methods: {
getList(param) {
this.gerCarData(param)
},
async gerCarData(param) {
this.isLoading1 = true
this.isLoading2 = true
this.isLoading3 = true
this.isLoading4 = true
this.carParamInfo = {
...param,
}
try {
let resBehavior = await postillegalAnalysisillegalAnalysisBehavior(
this.carParamInfo
)
let resPlace = await postillegalAnalysisillegalAnalysisPlace(
this.carParamInfo
)
let resCar = await postillegalAnalysisillegalAnalysisVehicle(
this.carParamInfo
)
let resTime = await postillegalAnalysisillegalAnalysisTime(
this.carParamInfo
)
let resCodeBehavior = await getalarmRulequeryRulesByAlarmCode({
alarmCode: 'C03A04A01A01',
})
let resCodePlace = await getalarmRulequeryRulesByAlarmCode({
alarmCode: 'C03A04A01A02',
})
let resCodeCar = await getalarmRulequeryRulesByAlarmCode({
alarmCode: 'C03A04A01A03',
})
if (resCodeBehavior.status == 0 && resCodeBehavior.data) {
this.BehaviorAlarmValue =
Number(resCodeBehavior.data[0]?.alarmNum) || 0
}
if (resCodePlace.status == 0 && resCodePlace.data) {
this.PlaceAlarmValue = Number(resCodePlace.data[0]?.alarmNum) || 0
}
if (resCodeCar.status == 0 && resCodeCar.data) {
this.CarAlarmValue = Number(resCodeCar.data[0]?.alarmNum) || 0
}
if (resBehavior.status == 0 && resBehavior.data) {
// this.BehaviorEchartData = resBehavior.data
this.BehaviorEchartData = resBehavior.data.map(v => {
return {
name: v.wfxwmc,
value: v.sl,
}
})
this.render('behavior', this.BehaviorAlarmValue)
}
if (resPlace.status == 0 && resPlace.data) {
this.placeEchartData = resPlace.data.map(v => {
return {
name: v.wfdz,
value: v.sl,
}
})
this.render('place', this.PlaceAlarmValue)
}
if (resCar.status == 0 && resCar.data) {
this.carEchartData = resCar.data.map(v => {
return {
name: v.hphm,
value: v.sl,
}
})
this.render('car', this.CarAlarmValue)
}
if (resTime.status == 0 && resTime.data) {
this.TimeEchartData = resTime.data.map(v => {
return {
name: v.name,
value: v.num,
}
})
this.render('time')
}
this.isLoading1 = false
this.isLoading2 = false
this.isLoading3 = false
this.isLoading4 = false
} catch (error) {
this.isLoading1 = false
this.isLoading2 = false
this.isLoading3 = false
this.isLoading4 = false
}
},
render(str, threshold) {
console.log(888)
if (str === 'behavior') {
this.showEmpty1 = this.BehaviorEchartData.length > 0 ? false : true
if (this.BehaviorEchartData.length == 0) return
this.Option1 = this.setOption(this.BehaviorEchartData, str, threshold)
} else if (str === 'place') {
this.showEmpty2 = this.placeEchartData.length > 0 ? false : true
if (this.placeEchartData.length == 0) return
this.Option2 = this.setOption(this.placeEchartData, str, threshold)
} else if (str === 'car') {
this.showEmpty3 = this.carEchartData.length > 0 ? false : true
if (this.carEchartData.length == 0) return
this.Option3 = this.setOption(this.carEchartData, str, threshold)
} else if (str === 'time') {
this.showEmpty4 = this.TimeEchartData.length > 0 ? false : true
if (this.TimeEchartData.length == 0) return
this.Option4 = this.setOption(this.TimeEchartData, str, threshold)
}
},
setOption(data, str, threshold) {
if (str === 'behavior' || str === 'place' || str === 'car') {
let dataZoom = [
{
show: true,
// 设置类型
type: 'slider',
// 设置背景颜色
backgroundColor: 'transparent',
// 设置选中范围的填充颜色
fillerColor: '#64B1FF',
// 设置边框颜色
borderColor: 'transparent',
// 是否显示detail,即拖拽时候显示详细数值信息
showDetail: false,
// 数据窗口范围的起始数值
startValue: 0,
// 数据窗口范围的结束数值(一页显示多少条数据)
endValue: 9,
// 控制哪个轴,如果是number表示控制一个轴,
// 如果是Array表示控制多个轴。此处控制第二根轴
xAxisIndex: [0],
// empty:当前数据窗口外的数据,被设置为空。
// 即不会影响其他轴的数据范围
// filterMode: "empty",
// 滚动条高度
// width: 6,
// 滚动条显示位置
height: '3%',
// 距离右边
right: 20,
// 如果top的值为'top', 'middle', 'bottom',组件会根据相应的位置自动对齐
bottom: 20,
// left: "center",
// 控制手柄的尺寸
handleSize: 0,
// 是否锁定选择区域(或叫做数据窗口)的大小
zoomLoxk: true,
// 组件离容器上侧的距离
showDataShadow: false, //是否显示数据阴影 默认auto
// showDetail: false, //即拖拽时候是否显示详细数值信息 默认true
moveHandleSize: 0, //两侧滑块宽度
handleStyle: {
borderColor: '#cacaca',
borderWidth: '5',
shadowBlur: 2,
background: '#ddd',
shadowColor: '#ddd',
borderRadius: 40,
},
// borderRadius: 40,
},
{
// 没有下面这块的话,只能拖动滚动条,
// 鼠标滚轮在区域内不能控制外部滚动条
type: 'inside',
// 控制哪个轴,如果是number表示控制一个轴,
// 如果是Array表示控制多个轴。此处控制第二根轴
xAxisIndex: [0],
// 滚轮是否触发缩放
zoomOnMouseWheel: false,
// 鼠标移动能否触发平移
moveOnMouseMove: true,
// 鼠标滚轮能否触发平移
moveOnMouseWheel: true,
start: 0,
},
]
let option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
enterable: true,
confine: true,
// position: point => {
// return [...point]
// },
borderColor: 'rgba(251, 249, 249, 0)',
padding: 10,
// formatter: p => {
// return `<span style="font-size:14px;color:#666;font-weight:400;margin-left:2px">${p[0].data}次</span>`
// },
},
legend: {
show: false,
},
grid: {
left: '1%',
right: '1%',
bottom: '13%',
top: '18%',
containLabel: true,
},
xAxis: {
type: 'category',
axisTick: {
show: false,
},
grid: {
bottom: 0,
},
axisLine: {
show: false,
},
splitLine: {
show: false,
},
axisLabel: {
//x轴字体颜色
show: true, //是否显示刻度标签
interval: '0', // 刻度标签的显示间隔,在x轴中有效.0显示所有
inside: false, // 刻度标签是否朝内,默认朝外
// rotate: 50, // 刻度标签旋转的角度,旋转的角度从-90度到90度
width: 80,
overflow: 'truncate',
ellipsis: '...',
},
data: data.map(item => item.name),
},
yAxis: {
type: 'value',
position: 'left',
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
color: '#999',
},
splitLine: {
show: false,
},
},
dataZoom: [],
series: [
{
name: 'Fake Data',
type: 'line',
showSymbol: false,
data: [threshold],
tooltip: {
show: false,
},
markLine: {
symbol: ['none', 'none'], // 去掉箭头
label: {
show: false,
position: 'start',
formatter: '{b}',
},
data: [
{
name: '阈值',
yAxis: threshold,
},
],
lineStyle: {
type: 'dashed',
color: '#f82020',
width: 1,
},
},
},
{
name: '违法数量',
type: 'bar',
data: data.map(item => {
if (threshold && item.value > threshold) {
return {
value: item.value,
itemStyle: {
borderRadius: [9, 9, 0, 0],
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#FF8D64' },
{ offset: 1, color: '#FE5E39' },
]),
},
}
} else {
return {
value: item.value,
itemStyle: {
borderRadius: [9, 9, 0, 0],
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#64B1FF' },
{ offset: 1, color: '#3986FE' },
]),
},
}
}
}),
barWidth: 11,
tooltip: {
valueFormatter: function (value) {
return value
},
},
// markLine: {
// symbol: ['none', 'none'],
// label: {
// show: false,
// },
// lineStyle: { color: '#FE5E39' },
// data: [
// {
// yAxis: threshold,
// },
// ],
// },
},
],
}
if (data.length > 10) {
option.dataZoom = dataZoom
} else {
option.dataZoom = []
}
return option
} else {
let option2 = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
enterable: true,
confine: true,
position: point => {
return [...point]
},
formatter: param => {
let p = param[0]
// let info = data.find(item => item.name == p.name)
// let perNum = info.zb
// let total = info.total
// let clickPobj = {
// apiId: '3',
// data: {
// // wflx: this.mainRadio,
// name: p.name,
// },
// }
// let clickP = JSON.stringify(clickPobj).replace(/\"/g, "'") // eslint-disable-line
// let perNum = ((p.value / total) * 100).toFixed(2)
let str1 = `<span style="font-size:14px;color:#666;font-weight:400;margin-left:2px">${p.name}<span style="margin-left:20px;font-size:14px;font-weight:900;color:#409EFF;cursor:pointer">${p.value}</span>`
return str1
},
},
color: ['#0798FF'],
grid: {
left: '1%',
right: '1%',
bottom: '3%',
top: '18%',
containLabel: true,
},
xAxis: {
type: 'category',
data: data.map(item => item.name),
axisTick: {
show: false,
},
grid: {
bottom: 0,
},
axisLine: {
show: false,
},
splitLine: {
show: false,
},
axisLabel: {
//x轴字体颜色
show: true, //是否显示刻度标签
interval: '0', // 刻度标签的显示间隔,在x轴中有效.0显示所有
inside: false, // 刻度标签是否朝内,默认朝外
// rotate: 50, // 刻度标签旋转的角度,旋转的角度从-90度到90度
width: 100,
overflow: 'truncate',
ellipsis: '...',
},
},
yAxis: [
{
type: 'value',
name: '起',
position: 'left',
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
color: '#999',
},
splitLine: {
show: false,
},
},
],
series: [
{
name: '违法数量',
type: 'line',
showSymbol: false,
data: data.map(item => item.value),
smooth: true,
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: 'rgba(7, 152, 255, 0.16)', // 0% 处的颜色
},
{
offset: 1,
color: 'rgba(0,131,255,0)', // 100% 处的颜色
},
],
global: false, // 缺省为 false
},
},
},
],
}
return option2
}
},
},
mounted() {},
}
</script>
<style lang="less" scoped>
.chart_con {
position: relative;
width: 100%;
height: 380px;
padding: 16px 23px;
margin-bottom: 13px;
background: #fff;
border-radius: 5px;
box-shadow: 0 5px 20px 0 rgb(179 182 185 / 40%);
}
.module-title {
display: flex;
align-items: center;
font-size: 16px;
font-weight: bolder;
line-height: 22px;
color: #222b45;
img {
width: 24px;
height: 24px;
margin-right: 3px;
}
}
.earlyWarning-container {
width: 100%;
}
</style>