385 lines
11 KiB
Vue
385 lines
11 KiB
Vue
<template>
|
|
<div ref="chartContainer" class="chartContainer" style="position: relative; width: 100%; height: 100%;" />
|
|
</template>
|
|
|
|
<script>
|
|
import echarts from 'echarts'
|
|
import resize from '@/views/OperationalOverview/components/mixins/resize'
|
|
import { Random } from 'mockjs'
|
|
|
|
class ChartOption {
|
|
constructor() {
|
|
this.color = ['#DDB112', '#1A99FF', '#FB418C', '#A691FF', '#49FBD6']
|
|
|
|
this.legend = {
|
|
top: 14,
|
|
right: 22,
|
|
itemWidth: 6,
|
|
itemHeight: 8,
|
|
textStyle: {
|
|
color: '#DFF1FECC',
|
|
fontSize: 12
|
|
}
|
|
}
|
|
|
|
this.grid = {
|
|
top: 72,
|
|
left: 12,
|
|
right: 28,
|
|
bottom: 20,
|
|
containLabel: true
|
|
}
|
|
|
|
this.tooltip = {
|
|
trigger: 'axis',
|
|
padding: 10,
|
|
backgroundColor: 'rgba(13, 29, 53, 0.8)',
|
|
extraCssText: 'width: 180px !important; ',
|
|
axisPointer: {
|
|
type: 'line',
|
|
lineStyle: {
|
|
type: 'dotted',
|
|
color: '#7BFFFB'
|
|
}
|
|
},
|
|
formatter: params => {
|
|
return `
|
|
<div style="display: flex; flex-direction: column; gap: calc(4px * var(--beilv));">
|
|
<h2 style="font-size: calc(14px * var(--beilv)); margin: 0 0 4px; font-weight: normal; color: white;">${params[0].axisValue}</h2>
|
|
<span style="display: flex; align-items: center; gap: 8px;"><span style="width: 10px; height: 10px; border-radius: 5px; background: ${
|
|
this.color[0]
|
|
}"></span><span>${params[0].seriesName}: ${params[0].value}</span></span>
|
|
<span style="display: flex; align-items: center; gap: 8px;"><span style="width: 10px; height: 10px; border-radius: 5px; background: ${
|
|
this.color[1]
|
|
}"></span><span>${params[1].seriesName}: ${params[1].value}</span></span>
|
|
</div>
|
|
`
|
|
}
|
|
}
|
|
|
|
let today = new Date()
|
|
this.xAxis = {
|
|
type: 'category',
|
|
boundaryGap: false,
|
|
axisLine: {
|
|
lineStyle: {
|
|
color: '#fff3'
|
|
}
|
|
},
|
|
axisTick: { show: false },
|
|
axisLabel: {
|
|
textStyle: {
|
|
fontSize: 12,
|
|
color: '#fff8' //
|
|
},
|
|
margin: 12
|
|
},
|
|
data:
|
|
this.mode === 'month'
|
|
? Array(new Date(today.getFullYear(), today.getMonth() + 1, 0).getDate())
|
|
.fill(1)
|
|
.map((_, idx) => idx + 1)
|
|
: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
|
|
}
|
|
|
|
this.yAxis = [
|
|
{
|
|
name: '成品率 ',
|
|
type: 'value',
|
|
min: '80',
|
|
splitNumber: 4,
|
|
nameGap: 16,
|
|
nameTextStyle: {
|
|
color: 'rgba(255,255,255,0.7)',
|
|
fontSize: 12,
|
|
align: 'left',
|
|
verticalAlign: 'bottom'
|
|
},
|
|
axisLine: {
|
|
lineStyle: {
|
|
type: 'solid',
|
|
color: 'rgba(119, 255, 242, 0.6)', // 左边线的颜色
|
|
width: '1' // 坐标线的宽度
|
|
}
|
|
},
|
|
axisTick: {
|
|
show: false
|
|
},
|
|
axisLabel: {
|
|
formatter: '{value} %',
|
|
textStyle: {
|
|
fontSize: 12,
|
|
color: 'rgba(255,255,255,0.5)' // 坐标值得具体的颜色
|
|
}
|
|
},
|
|
splitLine: {
|
|
lineStyle: {
|
|
type: 'dotted',
|
|
color: 'rgba(119, 255, 242, 0.2)'
|
|
}
|
|
}
|
|
}
|
|
]
|
|
|
|
this.series = [
|
|
{
|
|
name: 'A1下片机',
|
|
type: 'line',
|
|
// symbol: 'none',
|
|
symbol: 'circle',
|
|
symbolSize: 1,
|
|
showSymbol: false,
|
|
// smooth: true,
|
|
areaStyle: {
|
|
// color: 'rgba(50,145,152,0.5)'
|
|
color: {
|
|
type: 'linear',
|
|
x: 0,
|
|
y: 0,
|
|
x2: 0,
|
|
y2: 1,
|
|
colorStops: [
|
|
{
|
|
offset: 0,
|
|
color: '#DDB11266' // 0% 处的颜色
|
|
},
|
|
{
|
|
offset: 1,
|
|
color: 'transparent' // 100% 处的颜色
|
|
}
|
|
],
|
|
global: false // 缺省为 false
|
|
}
|
|
},
|
|
emphasis: {
|
|
focus: 'series',
|
|
scale: 1.2
|
|
},
|
|
data:
|
|
this.mode === 'month'
|
|
? Array(30)
|
|
.fill(1)
|
|
.map(_ => Random.integer(94, 99))
|
|
: Array(7)
|
|
.fill(1)
|
|
.map(_ => Random.integer(94, 99))
|
|
},
|
|
{
|
|
name: '磨边机',
|
|
type: 'line',
|
|
// symbol: 'none',
|
|
symbol: 'circle',
|
|
symbolSize: 1,
|
|
showSymbol: false,
|
|
// smooth: true,
|
|
areaStyle: {
|
|
// color: 'rgba(50,145,152,0.5)'
|
|
color: {
|
|
type: 'linear',
|
|
x: 0,
|
|
y: 0,
|
|
x2: 0,
|
|
y2: 1,
|
|
colorStops: [
|
|
{
|
|
offset: 0,
|
|
color: '#1A99FFCC' // 0% 处的颜色
|
|
},
|
|
{
|
|
offset: 1,
|
|
color: 'transparent' // 100% 处的颜色
|
|
}
|
|
],
|
|
global: false // 缺省为 false
|
|
}
|
|
},
|
|
emphasis: {
|
|
focus: 'series'
|
|
},
|
|
data:
|
|
this.mode === 'month'
|
|
? Array(30)
|
|
.fill(1)
|
|
.map(_ => Random.integer(94, 99))
|
|
: Array(7)
|
|
.fill(1)
|
|
.map(_ => Random.integer(94, 99))
|
|
}
|
|
]
|
|
}
|
|
|
|
get option() {
|
|
return this
|
|
}
|
|
|
|
optionFilter(option, calcSize = () => {} /** callback */) {
|
|
let newOption
|
|
if (Array.isArray(option)) {
|
|
newOption = []
|
|
option.forEach(item => {
|
|
newOption.push(this.optionFilter(item, calcSize))
|
|
})
|
|
return newOption
|
|
} else if (typeof option === 'object') {
|
|
newOption = {}
|
|
for (const key in option) {
|
|
if (key === 'colorStops') newOption[key] = option[key]
|
|
else if (
|
|
typeof option[key] === 'number' /** 过滤不做变化的属性 */ &&
|
|
['splitNumber', 'x', 'x2', 'y', 'y2', 'yAxisIndex', 'xAxisIndex'].indexOf(key) === -1
|
|
) {
|
|
newOption[key] = calcSize(option[key])
|
|
} else newOption[key] = this.optionFilter(option[key], calcSize)
|
|
}
|
|
return newOption
|
|
} else {
|
|
newOption = calcSize(option)
|
|
return option
|
|
}
|
|
}
|
|
}
|
|
|
|
export default {
|
|
name: 'PlFaultAnalysisPieChart',
|
|
mixins: [resize],
|
|
props: {
|
|
mode: {
|
|
type: String,
|
|
default: '',
|
|
validator: val => ['month', 'day'].indexOf(val) !== -1
|
|
},
|
|
dataUpdateToken: {
|
|
type: String,
|
|
default: 'default-token'
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
chart: null,
|
|
configs: null
|
|
}
|
|
},
|
|
|
|
watch: {
|
|
dataUpdateToken(val) {
|
|
this.refreshData()
|
|
}
|
|
},
|
|
|
|
mounted() {
|
|
this.$nextTick(() => {
|
|
if (!this.chart) this.chart = echarts.init(this.$refs.chartContainer)
|
|
this.setChartOption()
|
|
})
|
|
},
|
|
methods: {
|
|
refreshData() {
|
|
// update xaxis
|
|
let today = new Date()
|
|
this.configs.xAxis.data =
|
|
this.mode === 'month'
|
|
? Array(new Date(today.getFullYear(), today.getMonth() + 1, 0).getDate())
|
|
.fill(1)
|
|
.map((_, idx) => idx + 1)
|
|
: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
|
|
|
|
// update tooltip
|
|
if (this.mode === 'month') {
|
|
this.configs.tooltip = {
|
|
trigger: 'axis',
|
|
padding: 10,
|
|
backgroundColor: 'rgba(13, 29, 53, 0.8)',
|
|
extraCssText: 'width: 180px !important; ',
|
|
axisPointer: {
|
|
type: 'line',
|
|
lineStyle: {
|
|
type: 'dotted',
|
|
color: '#7BFFFB'
|
|
}
|
|
},
|
|
formatter: params => {
|
|
const currentMonth = new Date().getMonth() + 1
|
|
return `
|
|
<div style="display: flex; flex-direction: column; gap: calc(4px * var(--beilv));">
|
|
<h2 style="font-size: calc(14px * var(--beilv)); margin: 0 0 4px; font-weight: normal; color: white;">${currentMonth}-${
|
|
params[0].axisValue
|
|
}</h2>
|
|
<span style="display: flex; align-items: center; gap: 8px;"><span style="width: 10px; height: 10px; border-radius: 5px; background: ${
|
|
this.configs.color[0]
|
|
}"></span><span>${params[0].seriesName}: ${params[0].value}</span></span>
|
|
<span style="display: flex; align-items: center; gap: 8px;"><span style="width: 10px; height: 10px; border-radius: 5px; background: ${
|
|
this.configs.color[1]
|
|
}"></span><span>${params[1].seriesName}: ${params[1].value}</span></span>
|
|
</div>
|
|
`
|
|
}
|
|
}
|
|
} else if (this.mode === 'day') {
|
|
this.configs.tooltip = null
|
|
this.configs.tooltip = {
|
|
trigger: 'axis',
|
|
padding: 10,
|
|
backgroundColor: 'rgba(13, 29, 53, 0.8)',
|
|
extraCssText: 'width: 180px !important; ',
|
|
axisPointer: {
|
|
type: 'line',
|
|
lineStyle: {
|
|
type: 'dotted',
|
|
color: '#7BFFFB'
|
|
}
|
|
},
|
|
formatter: params => {
|
|
return `
|
|
<div style="display: flex; flex-direction: column; gap: calc(4px * var(--beilv));">
|
|
<h2 style="font-size: calc(14px * var(--beilv)); margin: 0 0 4px; font-weight: normal; color: white;">${
|
|
params[0].axisValue
|
|
}</h2>
|
|
<span style="display: flex; align-items: center; gap: 8px;"><span style="width: 10px; height: 10px; border-radius: 5px; background: ${
|
|
this.configs.color[0]
|
|
}"></span><span>${params[0].seriesName}: ${params[0].value}</span></span>
|
|
<span style="display: flex; align-items: center; gap: 8px;"><span style="width: 10px; height: 10px; border-radius: 5px; background: ${
|
|
this.configs.color[1]
|
|
}"></span><span>${params[1].seriesName}: ${params[1].value}</span></span>
|
|
</div>
|
|
`
|
|
}
|
|
}
|
|
}
|
|
|
|
// update series
|
|
this.configs.series.forEach(item => {
|
|
item.data =
|
|
this.mode === 'month'
|
|
? Array(30)
|
|
.fill(1)
|
|
.map(_ => Random.integer(94, 99))
|
|
: Array(7)
|
|
.fill(1)
|
|
.map(_ => Random.integer(94, 99))
|
|
})
|
|
|
|
if (this.chart) this.chart.setOption(this.configs)
|
|
},
|
|
calcSize(num) {
|
|
const beilv = document.documentElement.style.getPropertyValue('--beilv')
|
|
return num * beilv
|
|
},
|
|
setChartOption() {
|
|
let chartOption = new ChartOption()
|
|
this.configs = chartOption.optionFilter(chartOption.option, this.calcSize)
|
|
this.chart.setOption(this.configs)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.chartContainer >>> div {
|
|
width: 100% !important;
|
|
}
|
|
|
|
.diy-linestack-tooltip {
|
|
color: red;
|
|
}
|
|
</style>
|