11-mes-new/src/views/QualityManager/components/charts/newLineStack.vue
2022-11-25 15:43:03 +08:00

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>