devicesmgt/sgzb-screen/src/components/home/rightOne.vue

528 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="access-rate-page">
<div class="access-rate-box">
<div class="access-rate-box-title-bg">
<h5 class="access-rate-box-title">当月领料分析</h5>
</div>
<div class="chart-container">
<div
class="chart"
ref="chart"
id="pieChartMap"
@click="handleClick"
></div>
<!-- 底座背景 -->
<div class="bg"></div>
</div>
</div>
<materialAnalysisDialog
ref="materialAnalysisDialog"
></materialAnalysisDialog>
</div>
</template>
<script>
// import Highcharts from "highcharts/highstock";
// import HighchartsMore from "highcharts/highcharts-more";
// import HighchartsDrilldown from "highcharts/modules/drilldown";
// import Highcharts3D from "highcharts/highcharts-3d";
// HighchartsMore(Highcharts);
// HighchartsDrilldown(Highcharts);
// Highcharts3D(Highcharts);
import * as echarts from 'echarts'
import 'echarts-gl' // 3d图表库
import { getPickingAnalysisByMonthApi } from '../../api/screen'
import materialAnalysisDialog from './materialAnalysisDialog'
export default {
components: {
materialAnalysisDialog,
},
data() {
return {
data: [],
maType: '',
}
},
mounted() {
this.$eventBus.$on('maType', (maType) => {
this.maType = maType
this.getPickingAnalysisByMonthApiPage()
})
setInterval(() => {
this.getPickingAnalysisByMonthApiPage()
}, 60 * 1000)
},
destroyed() {
this.$eventBus.$off('maType')
},
methods: {
getPickingAnalysisByMonthApiPage() {
this.data = []
let params = {
maType: this.maType,
}
getPickingAnalysisByMonthApi(params).then((res) => {
if (res.code == 200) {
this.data.push(
{
name: '数量领料',
value: res.data.num,
rate: res.data.rate,
itemStyle: {
color: '#01F4F5',
},
},
{
name: '编码领料',
value: res.data.num2,
rate: res.data.rate2,
itemStyle: {
color: '#077E98',
},
}
)
this.mastery(this.data)
}
})
},
// 生成扇形的曲面参数方程,用于 series-surface.parametricEquation
getParametricEquation(
startRatio,
endRatio,
isSelected,
isHovered,
k,
height
) {
// 计算
let midRatio = (startRatio + endRatio) / 2
let startRadian = startRatio * Math.PI * 2
let endRadian = endRatio * Math.PI * 2
let midRadian = midRatio * Math.PI * 2
// 如果只有一个扇形,则不实现选中效果。
if (startRatio === 0 && endRatio === 1) {
isSelected = false
}
// 通过扇形内径/外径的值,换算出辅助参数 k默认值 1/3
k = typeof k !== 'undefined' ? k : 1 / 3
// 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0
let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0
let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0
// 计算高亮效果的放大比例(未高亮,则比例为 1
let hoverRate = isHovered ? 1.05 : 1
// 返回曲面参数方程
return {
u: {
min: -Math.PI,
max: Math.PI * 3,
step: Math.PI / 32,
},
v: {
min: 0,
max: Math.PI * 2,
step: Math.PI / 20,
},
x: function (u, v) {
if (u < startRadian) {
return (
offsetX +
Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
)
}
if (u > endRadian) {
return (
offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
)
}
return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate
},
y: function (u, v) {
if (u < startRadian) {
return (
offsetY +
Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
)
}
if (u > endRadian) {
return (
offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
)
}
return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate
},
z: function (u, v) {
if (u < -Math.PI * 0.5) {
return Math.sin(u)
}
if (u > Math.PI * 2.5) {
return Math.sin(u)
}
return Math.sin(v) > 0 ? 1 * height : -1
},
}
},
// 生成模拟 3D 饼图的配置项
getPie3D(pieData, internalDiameterRatio) {
let series = []
let sumValue = 0
let startValue = 0
let endValue = 0
let legendData = []
let k =
typeof internalDiameterRatio !== 'undefined'
? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
: 1 / 3
// 为每一个饼图数据,生成一个 series-surface 配置
for (let i = 0; i < pieData.length; i++) {
sumValue += pieData[i].value
let seriesItem = {
name:
typeof pieData[i].name === 'undefined'
? `series${i}`
: pieData[i].name,
type: 'surface',
parametric: true,
wireframe: {
show: false,
},
pieData: pieData[i],
pieStatus: {
selected: false,
hovered: false,
k: k,
},
}
if (typeof pieData[i].itemStyle != 'undefined') {
let itemStyle = {}
typeof pieData[i].itemStyle.color != 'undefined'
? (itemStyle.color = pieData[i].itemStyle.color)
: null
typeof pieData[i].itemStyle.opacity != 'undefined'
? (itemStyle.opacity = pieData[i].itemStyle.opacity)
: null
seriesItem.itemStyle = itemStyle
}
series.push(seriesItem)
}
for (let i = 0; i < series.length; i++) {
endValue = startValue + series[i].pieData.value
console.log(series[i])
series[i].pieData.startRatio = startValue / sumValue
series[i].pieData.endRatio = endValue / sumValue
series[i].parametricEquation = this.getParametricEquation(
series[i].pieData.startRatio,
series[i].pieData.endRatio,
false,
false,
k,
series[i].pieData.value
)
startValue = endValue
legendData.push(series[i].name)
}
// // 补充一个透明的圆环,用于支撑高亮功能的近似实现。
series.push({
name: 'mouseoutSeries',
type: 'surface',
parametric: true,
wireframe: {
show: false,
},
itemStyle: {
opacity: 0.1,
color: '#E1E8EC',
},
parametricEquation: {
u: {
min: 0,
max: Math.PI * 2,
step: Math.PI / 20,
},
v: {
min: 0,
max: Math.PI,
step: Math.PI / 20,
},
x: function (u, v) {
return ((Math.sin(v) * Math.sin(u) + Math.sin(u)) / Math.PI) * 2
},
y: function (u, v) {
return ((Math.sin(v) * Math.cos(u) + Math.cos(u)) / Math.PI) * 2
},
z: function (u, v) {
return Math.cos(v) > 0 ? -0.5 : -5
},
},
})
// // 补充一个透明的圆环,用于支撑高亮功能的近似实现。
series.push({
name: 'mouseoutSeries',
type: 'surface',
parametric: true,
wireframe: {
show: false,
},
itemStyle: {
opacity: 0.1,
color: '#E1E8EC',
},
parametricEquation: {
u: {
min: 0,
max: Math.PI * 2,
step: Math.PI / 20,
},
v: {
min: 0,
max: Math.PI,
step: Math.PI / 20,
},
x: function (u, v) {
return ((Math.sin(v) * Math.sin(u) + Math.sin(u)) / Math.PI) * 2
},
y: function (u, v) {
return ((Math.sin(v) * Math.cos(u) + Math.cos(u)) / Math.PI) * 2
},
z: function (u, v) {
return Math.cos(v) > 0 ? -5 : -7
},
},
})
series.push({
name: 'mouseoutSeries',
type: 'surface',
parametric: true,
wireframe: {
show: false,
},
itemStyle: {
opacity: 0.1,
color: '#E1E8EC',
},
parametricEquation: {
u: {
min: 0,
max: Math.PI * 2,
step: Math.PI / 20,
},
v: {
min: 0,
max: Math.PI,
step: Math.PI / 20,
},
x: function (u, v) {
return ((Math.sin(v) * Math.sin(u) + Math.sin(u)) / Math.PI) * 2.2
},
y: function (u, v) {
return ((Math.sin(v) * Math.cos(u) + Math.cos(u)) / Math.PI) * 2.2
},
z: function (u, v) {
return Math.cos(v) > 0 ? -7 : -7
},
},
})
return series
},
mastery(data) {
var myChart = echarts.init(document.querySelector('#pieChartMap'))
// const optionsData = [
// {
// name: '数量领料',
// value: 76,
// itemStyle: {
// color: '#01F4F5',
// },
// },
// {
// name: '编码领料',
// value: 24,
// itemStyle: {
// color: '#077E98',
// },
// },
// ];
const series = this.getPie3D(this.data, 0.8, 360, 18, 56, 1)
series.push({
type: 'pie',
label: {
opacity: 1,
fontSize: 14,
lineHeight: 15,
textStyle: {
fontSize: 14,
},
},
labelLine: {
length: 10,
length2: 30,
},
startAngle: 40, //起始角度,支持范围[0, 360]。
clockwise: false, //饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式
radius: ['12%', '62%'],
center: ['50%', '50%'],
data: this.data,
itemStyle: {
opacity: 0,
},
})
let option = {
legend: {
show: false,
tooltip: {
show: true,
},
},
animation: true,
title: {
x: 'center',
top: '20',
textStyle: {
color: '#fff',
fontSize: 14,
},
},
backgroundColor: '#333',
labelLine: {
show: true,
lineStyle: {
color: '#7BC0CB',
},
},
label: {
show: true,
position: 'inside',
formatter: (params) => {
return `${params.percent}%\n${params.name}`
},
borderWidth: 0,
padding: [0, -50],
height: 70,
fontSize: 14,
align: 'center',
color: '#ffffff',
rich: {
hr: {
backgroundColor: '#fff',
borderRadius: 3,
width: 3,
height: 3,
padding: [3, 3, 0, -12],
},
},
// rich: {
// b: {
// fontSize: 14,
// lineHeight: 20,
// color: "#ffffff",
// },
// c: {
// fontSize: 14,
// lineHeight: 25,
// color: "#ffffff",
// },
// },
},
xAxis3D: {
min: -1,
max: 1,
},
yAxis3D: {
min: -1,
max: 1,
},
zAxis3D: {
min: -1,
max: 1,
},
grid3D: {
show: false,
boxHeight: 0.2,
top: '-15%',
environment: '#010B3F',
viewControl: {
distance: 150,
alpha: 20,
beta: 0,
autoRotate: false, // 自动旋转
},
},
series: series,
}
if (option && typeof option === 'object') {
myChart.setOption(option)
}
},
handleClick() {
this.$refs.materialAnalysisDialog.setOpen({
open: true,
maType: this.maType,
})
},
},
}
</script>
<style lang="scss" scoped>
.access-rate-page {
margin-bottom: 31px;
z-index: 2001;
.access-rate-box {
.access-rate-box-title-bg {
width: 433px;
height: 50px;
background: url(../../assets/img/myImage/title_right.png) no-repeat center;
background-size: 100% 100%;
position: relative;
.access-rate-box-title {
position: absolute;
left: 6%;
top: 28%;
font-size: 20px;
font-family: Alibaba PuHuiTi, AlibabaPuHuiTi;
font-weight: 500;
color: #ffffff;
line-height: 23px;
letter-spacing: 2px;
}
}
.chart-container {
margin: 12px 0;
width: 433px;
height: 113px;
.chart {
width: 100%;
height: 200px;
}
// .bg {
// width: 337px;
// height: 144px;
// background: center top url(../../assets/img/myImage/bg.png)
// no-repeat;
// background-size: cover;
// margin-top: -120px;
// margin-left: 18%;
// }
}
}
}
</style>