| | |
| | | import { getAction, deleteAction, putAction, postAction, httpAction } from '@/api/manage' |
| | | |
| | | export default { |
| | | // è·åææè½¦é´ä¿¡æ¯ |
| | | getAllWorkShop: id => getAction('/mdc/home/getAllWorkShop', {}), |
| | | // æ ¹æ®ç¨æ·IDè·åç¨æ·ä¿¡æ¯ |
| | | getUserByIdApi: id => getAction('sys/api/getUserById', { id }), |
| | | // 设å¤è¿è¡ç¶æ |
| | | getEquipmentStatusStatisticsApi: productionId => getAction('/mdc/home/equipmentStatusStatistics', { productionId }), |
| | | // 设å¤å©ç¨ç |
| | | getEquipmentUtilizationStatisticsApi: productionId => getAction('/mdc/home/equipmentUtilizationStatistics', { productionId }), |
| | | // å
¨åå15天å©ç¨çæçº¿å¾ |
| | | getEquipmentDayUtilizationStatisticsApi: productionId => getAction('/mdc/home/equipmentDayUtilizationStatistics', { productionId }), |
| | | // 设å¤OEEç»è®¡ |
| | | getEquipmentOEEStatistics: productionId => getAction('/mdc/home/equipmentOEEStatistics', { productionId }), |
| | | // 设å¤OEEåå©ç¨çå¯¹æ¯ |
| | | getEquipmentMonthStatisticsApi: productionId => getAction('/mdc/home/equipmentMonthStatistics', { productionId }), |
| | | } |
| | |
| | | :type="collapsed ? 'menu-unfold' : 'menu-fold'" |
| | | @click="toggle"/> |
| | | |
| | | <span v-if="device === 'desktop'">欢è¿è¿å
¥ Jeecg-Boot ä¼ä¸çº§ä½ä»£ç å¹³å°</span> |
| | | <span v-else>Jeecg-Boot</span> |
| | | <span v-if="device === 'desktop'">欢è¿è¿å
¥ MDCæºæ
§è½¦é´</span> |
| | | |
| | | <user-menu :theme="theme"/> |
| | | </div> |
| | |
| | | <template> |
| | | <Component :is="currentSignage" :userType="userType" :productionCode="productionCode" |
| | | <Component :is="currentSignage" |
| | | :userType="userType" |
| | | :productionCode="productionCode" |
| | | :workshopSectionProductionCode="workshopSectionProductionCode" |
| | | v-if="[1,2,3,4].includes(userType)" |
| | | > |
| | | </Component> |
| | | <div v-else> <!-- ä¸ç»ä»¶æ¸²æäºæ¥ --> |
| | | <img src="@/assets/index.png" style="width: 100%;height: 785px"> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import signageApi from '@/api/signage' |
| | | import MdcManagerSignage from './mdcIndex/MdcManagerSignage.vue' |
| | | import DncManagerSignage from './dncIndex/DncManagerSignage.vue' |
| | | |
| | | export default { |
| | | name: "Analysis", |
| | | components: { |
| | | MdcManagerSignage, |
| | | DncManagerSignage |
| | | }, |
| | | data() { |
| | |
| | | productionCode: '', |
| | | branchFactoryProductionCode: '', |
| | | workshopSectionProductionCode: '', |
| | | userType: '' |
| | | userType: '', |
| | | } |
| | | }, |
| | | created() { |
| | |
| | | }, |
| | | methods: { |
| | | showModuleByUserInfo() { |
| | | const id = JSON.parse(localStorage.getItem('pro__Login_Userinfo')).value.id |
| | | // å®å
¨å¤çï¼å
夿localStorage䏿¯å¦åå¨ç¨æ·ä¿¡æ¯ï¼é¿å
JSON.parseæ¥é |
| | | const userInfoStr = localStorage.getItem('pro__Login_Userinfo') |
| | | if (!userInfoStr) { |
| | | this.currentSignage = '' // æ ç¨æ·ä¿¡æ¯æ¶ä¸æ¸²æç»ä»¶ |
| | | return |
| | | } |
| | | |
| | | const id = JSON.parse(userInfoStr).value.id |
| | | signageApi.getUserByIdApi(id) |
| | | .then(res => { |
| | | console.log("res", res.userType) |
| | | this.userType = res.userType |
| | | this.userType = res.userType // èµå¼åèªå¨è§¦åæ¡ä»¶æ¸²æå¤æ |
| | | // æ ¹æ®userTypeå¹é
对åºç»ä»¶ï¼æ¢å¤case1åcase4çé»è¾ï¼ |
| | | switch (this.userType) { |
| | | // case 1: |
| | | // //åå
·ç®¡ç |
| | | // this.currentSignage = 'EquipmentSignage' |
| | | // break |
| | | // case 2: |
| | | // //mdc |
| | | // this.currentSignage = 'WorkshopSectionSignage' |
| | | // break |
| | | case 2: |
| | | // mdc |
| | | this.currentSignage = 'MdcManagerSignage' |
| | | break |
| | | case 3: |
| | | //dnc |
| | | this.currentSignage = 'DncManagerSignage' |
| | |
| | | break |
| | | } |
| | | }) |
| | | .catch(err => { |
| | | // æ¥å£è¯·æ±å¤±è´¥æ¶ï¼é»è®¤æ¾ç¤ºå¾ç |
| | | console.error('è·åç¨æ·ç±»å失败ï¼', err) |
| | | this.userType = '' |
| | | this.currentSignage = '' |
| | | }) |
| | | } |
| | | } |
| | | } |
| | |
| | | margin: 0; |
| | | box-sizing: border-box; |
| | | /* æ°å¢ï¼è®¾ç½®å®¹å¨æå¤§é«åº¦ï¼å¯æ ¹æ®é¡µé¢å¸å±è°æ´ï¼å¦500px/80vhï¼ */ |
| | | max-height: 80vh; |
| | | max-height: 100vh; |
| | | /* æ°å¢ï¼åç´æ¹åæº¢åºæ¶æ¾ç¤ºæ»å¨æ¡ï¼æ°´å¹³æ¹å溢åºéèï¼é¿å
å¸å±éä¹±ï¼ */ |
| | | overflow-y: auto; |
| | | overflow-x: hidden; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="home-container"> |
| | | <div class="tab-nav"> |
| | | <div |
| | | v-for="(tab, index) in tabList" |
| | | :key="index" |
| | | :class="['tab-item', activeTab === index ? 'tab-active' : '']" |
| | | @click="handleTabChange(index)" |
| | | > |
| | | {{ tab.label }} |
| | | </div> |
| | | </div> |
| | | |
| | | |
| | | <div class="chart-container"> |
| | | <div class="left-cards"> |
| | | <div class="card left-cards-card"> |
| | | <div id="running_state_chart" style="width:100%;height: 45%;max-height: 45vh"></div> |
| | | <div id="efficiency_chart" style="width: 100%;height: 55%;max-height: 55vh"></div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="right-cards"> |
| | | <div class="card right-top-card"> |
| | | <div id="first15DaysEfficiency_chart" style="width:100%;height: 100%;max-height: 50vh"></div> |
| | | </div> |
| | | |
| | | <div class="right-bottom-card"> |
| | | <div class="card right-bottom-left-card"> |
| | | <div id="bar_chart" style="width:100%;height: 100%;max-height: 50vh"></div> |
| | | </div> |
| | | <div class="card right-bottom-right-card"> |
| | | <div id="double_bar_chart" style="width:100%;height: 100%;max-height: 50vh"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | |
| | | import signageApi from '@/api/signage' |
| | | import moment from 'moment' |
| | | |
| | | export default { |
| | | name: 'DncManagerSignage', |
| | | components: {}, |
| | | data() { |
| | | return { |
| | | tabList: [], |
| | | activeTab: -1, // åå§æ éä¸é¡µç¾ï¼-1表示æªéæ©ç¶æï¼ |
| | | firstEnterClientWidth: null, |
| | | pieChartRadius: ['45%', '55%'], |
| | | normalPieChartRadius: ['45%', '55%'], |
| | | currentPageProductionId: null, |
| | | runningStateChart: '', |
| | | efficiencyChart: '', |
| | | efficiencyData: [], |
| | | barChart: '', |
| | | barChartData: [], |
| | | doubleBarChart: '', |
| | | doubleBarChartData: {}, |
| | | runningStateChartDataRequireFinished: false, |
| | | first15DaysEfficiencyChart: '', |
| | | first15DaysEfficiencyData: { |
| | | dataList: [], |
| | | dateList: [] |
| | | }, |
| | | runningStateData: [ |
| | | { value: '0', name: 'å
³æº' }, |
| | | { value: '0', name: 'æ¥è¦' }, |
| | | { value: '0', name: 'å¾
æº' }, |
| | | { value: '0', name: 'è¿è¡' } |
| | | ] |
| | | } |
| | | }, |
| | | mounted() { |
| | | window.addEventListener('resize', this.handleWindowResize) |
| | | // this.re_drawPieChart() |
| | | this.getAllWorkShop() |
| | | this.getChartDataByApi() |
| | | }, |
| | | beforeDestroy() { |
| | | // ç»ä»¶éæ¯åç§»é¤çå¬ |
| | | window.removeEventListener('resize', this.handleWindowResize) |
| | | this.destroyEchartsInstances() |
| | | }, |
| | | methods: { |
| | | |
| | | getAllWorkShop() { |
| | | this.tabList = [] |
| | | signageApi.getAllWorkShop() |
| | | .then(res => { |
| | | if (res.success) { |
| | | this.tabList = res.result.map(workshop => ({ |
| | | label: workshop.productionName, |
| | | factoryId: workshop.id |
| | | })) |
| | | |
| | | if (this.tabList.length > 0) { |
| | | this.activeTab = -1 |
| | | this.destroyEchartsInstances() |
| | | this.getChartDataByApi() |
| | | } |
| | | } else { |
| | | this.tabList = [] |
| | | this.activeTab = -1 |
| | | } |
| | | }) |
| | | .catch(err => { |
| | | this.tabList = [] |
| | | this.activeTab = -1 |
| | | this.destroyEchartsInstances() |
| | | this.getChartDataByApi() |
| | | }) |
| | | }, |
| | | |
| | | destroyEchartsInstances() { |
| | | const charts = [ |
| | | this.runningStateChart, |
| | | this.efficiencyChart, |
| | | this.first15DaysEfficiencyChart, |
| | | this.barChart, |
| | | this.doubleBarChart |
| | | ] |
| | | charts.forEach(chart => { |
| | | if (chart && chart.dispose) chart.dispose() |
| | | }) |
| | | }, |
| | | |
| | | handleTabChange(index) { |
| | | // 1. 妿ç¹å»çæ¯âå·²éä¸ç页ç¾âï¼æ§è¡âåæ¶éä¸âé»è¾ |
| | | if (this.activeTab === index) { |
| | | this.activeTab = -1; // é置为æªéä¸ç¶æ |
| | | this.destroyEchartsInstances(); // 鿝ææå¾è¡¨å®ä¾ |
| | | this.getChartDataByApi(); |
| | | return; |
| | | } |
| | | |
| | | // 2. 常è§åæ¢é¡µç¾é»è¾ï¼åæé»è¾ä¿çï¼ |
| | | this.activeTab = index; |
| | | this.destroyEchartsInstances(); |
| | | this.getChartDataByApi(); |
| | | }, |
| | | |
| | | /* è°ç¨æ¥å£è·åå¾è¡¨æ°æ®æ±æ»æ¹æ³ */ |
| | | getChartDataByApi() { |
| | | let currentFactoryId = '' |
| | | if (this.tabList[this.activeTab] != null && this.tabList[this.activeTab] !== undefined) { |
| | | currentFactoryId = this.tabList[this.activeTab].factoryId |
| | | } |
| | | console.log('currentFactoryId', currentFactoryId) |
| | | this.getRunningStateDataByApi(currentFactoryId) |
| | | this.getEfficiencyDataByApi(currentFactoryId) |
| | | this.getFirst15DaysEfficiencyDataByApi(currentFactoryId) |
| | | this.getBarChartDataByApi(currentFactoryId) |
| | | this.getDoubleBarChartDataByApi(currentFactoryId) |
| | | }, |
| | | |
| | | /* è°ç¨æ¥å£è·å设å¤è¿è¡ç¶æ */ |
| | | getRunningStateDataByApi(productionCode) { |
| | | this.runningStateChart = this.$echarts.init(document.getElementById('running_state_chart')) |
| | | this.runningStateChart.showLoading({ |
| | | text: 'æ°æ®å è½½ä¸ ...', |
| | | color: '#0696e1', // å è½½å¨ç»é¢è² |
| | | textColor: '#fff', |
| | | maskColor: 'transparent' // é®ç½©å± |
| | | }) |
| | | signageApi.getEquipmentStatusStatisticsApi(productionCode) |
| | | .then(res => { |
| | | if (res.success) { |
| | | this.runningStateData = res.result.list |
| | | this.currentPageProductionId = res.result.productionId |
| | | this.runningStateChartDataRequireFinished = true |
| | | this.drawRunningStateChart(res.result.productionId) |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | /* è°ç¨æ¥å£è·å设å¤å©ç¨ç */ |
| | | getEfficiencyDataByApi(productionCode) { |
| | | this.efficiencyChart = this.$echarts.init(document.getElementById('efficiency_chart')) |
| | | this.efficiencyChart.showLoading({ |
| | | text: 'æ°æ®å è½½ä¸ ...', |
| | | color: '#0696e1', // å è½½å¨ç»é¢è² |
| | | textColor: '#fff' |
| | | }) |
| | | signageApi.getEquipmentUtilizationStatisticsApi(productionCode) |
| | | .then(res => { |
| | | if (res.success) { |
| | | this.efficiencyData = res.result |
| | | this.drawEfficiencyChart() |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | /* è°ç¨æ¥å£è·åå15天å©ç¨ç */ |
| | | getFirst15DaysEfficiencyDataByApi(productionCode) { |
| | | this.first15DaysEfficiencyChart = this.$echarts.init(document.getElementById('first15DaysEfficiency_chart')) |
| | | this.first15DaysEfficiencyChart.showLoading({ |
| | | text: 'æ°æ®å è½½ä¸ ...', |
| | | color: '#0696e1', // å è½½å¨ç»é¢è² |
| | | textColor: '#000000', |
| | | maskColor: 'transparent' // é®ç½©å± |
| | | }) |
| | | signageApi.getEquipmentDayUtilizationStatisticsApi(productionCode) |
| | | .then(res => { |
| | | if (res.success) { |
| | | this.first15DaysEfficiencyData = res.result |
| | | this.drawFirst15DaysEfficiencyDataChart() |
| | | } |
| | | }) |
| | | }, |
| | | /* ç»å¶å7天å©ç¨çæ±å¾ */ |
| | | drawFirst15DaysEfficiencyDataChart() { |
| | | this.first15DaysEfficiencyData.dateList.forEach(item => { |
| | | if (!this.first15DaysEfficiencyData.dataList.map(item => item.date).includes(item)) { |
| | | const dateObj = { |
| | | date: item.date, |
| | | openRate: 0, |
| | | startRate: 0, |
| | | utilizationRate: 0 |
| | | } |
| | | this.first15DaysEfficiencyData.dataList.push(dateObj) |
| | | } |
| | | }) |
| | | const dateList = this.first15DaysEfficiencyData.dataList.map(item => item.date) |
| | | const newData = { |
| | | xAxis: dateList, |
| | | yAxis: [ |
| | | { |
| | | name: 'å©ç¨ç', |
| | | value: this.first15DaysEfficiencyData.dataList.map(item => item.utilizationRate) |
| | | }, |
| | | { |
| | | name: 'å¼å¨ç', |
| | | value: this.first15DaysEfficiencyData.dataList.map(item => item.startRate) |
| | | }, |
| | | { |
| | | name: '弿ºç', |
| | | value: this.first15DaysEfficiencyData.dataList.map(item => item.openRate) |
| | | } |
| | | ], |
| | | yAxisName: 'å15天å©ç¨ç(%)' |
| | | } |
| | | let legendData = [] |
| | | let seriesData = [] |
| | | let colorArr = ['#A7F0C1', '#FAE893', '#66DFE2'] |
| | | legendData = newData.yAxis.map((item) => item.name) |
| | | seriesData = newData.yAxis.map((item1, index1) => { |
| | | return { |
| | | name: item1.name, |
| | | type: 'bar', |
| | | symbol: 'circle', |
| | | symbolSize: 8, |
| | | itemStyle: { |
| | | color: colorArr[index1], |
| | | barBorderRadius: 100 |
| | | }, |
| | | lineStyle: { |
| | | width: 2 |
| | | }, |
| | | markPoint: { |
| | | show: true |
| | | }, |
| | | yAxisIndex: 1, |
| | | data: item1.value // æçº¿å¾çæ°æ® |
| | | } |
| | | }) |
| | | const option = { |
| | | grid: { |
| | | containLabel: true, |
| | | bottom: '1%', |
| | | top: '20%', |
| | | left: '2%', |
| | | right: '1%' |
| | | }, |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'shadow' |
| | | }, |
| | | formatter: function(params) { |
| | | let result = '' |
| | | params.forEach((item, index) => { |
| | | let dom = `<span style="display:inline-block;width:10px;height:10px;border-radius:100px;margin-right:5px;background:${item.color}"></span>${item.seriesName}ï¼${item.value}%` |
| | | if (index === 0) { |
| | | result = `<span style="font-weight:bolder;">${item.name}</span>` |
| | | } |
| | | result += '<br />' + dom |
| | | }) |
| | | return result |
| | | } |
| | | }, |
| | | legend: { |
| | | top: 20, |
| | | right: 'center', |
| | | data: legendData, |
| | | itemGap: 10, |
| | | textStyle: { |
| | | fontSize: 14, |
| | | color: '#000000' |
| | | } |
| | | }, |
| | | xAxis: { |
| | | data: newData.xAxis || [], |
| | | axisLabel: { |
| | | interval: 0, |
| | | show: true, |
| | | fontSize: 14, |
| | | color: '#000000' |
| | | // rotate: -30, |
| | | }, |
| | | axisLine: { |
| | | show: true, |
| | | lineStyle: { |
| | | color: '#000000' |
| | | } |
| | | }, |
| | | axisTick: { |
| | | show: true, |
| | | alignWithLabel: true |
| | | } |
| | | }, |
| | | yAxis: [ |
| | | { |
| | | name: newData.yAxisName, |
| | | nameTextStyle: { |
| | | color: '#1AD8DE', |
| | | fontSize: 18, |
| | | padding: [0, 0, 0, 110] |
| | | }, |
| | | nameGap: 30, |
| | | type: 'value', |
| | | position: 'left', |
| | | axisLine: { |
| | | show: true, |
| | | lineStyle: { |
| | | color: '#000000' |
| | | } |
| | | }, |
| | | axisTick: { |
| | | show: false |
| | | }, |
| | | splitLine: { |
| | | show: false, |
| | | lineStyle: { |
| | | color: '#000000' |
| | | } |
| | | } |
| | | }, |
| | | { |
| | | type: 'value', |
| | | position: 'right', |
| | | splitNumber: 5, |
| | | max: 100, |
| | | axisLabel: { |
| | | show: true, |
| | | color: '#000000', |
| | | fontSize: 14 |
| | | }, |
| | | axisLine: { |
| | | show: true, |
| | | lineStyle: { |
| | | color: '#000000' |
| | | } |
| | | }, |
| | | axisTick: { |
| | | show: true |
| | | }, |
| | | splitLine: { |
| | | show: false, |
| | | lineStyle: { |
| | | color: '#000000' |
| | | } |
| | | } |
| | | } |
| | | ], |
| | | series: seriesData, |
| | | dataZoom: { |
| | | show: false, |
| | | startValue: 0, // ä»å¤´å¼å§ã |
| | | endValue: 14 // 䏿¬¡æ§å±ç¤ºå 个 |
| | | } |
| | | // toolbox: { |
| | | // show: true, |
| | | // feature: { |
| | | // mark: { show: true }, |
| | | // magicType: { show: true, type: ['line', 'bar'] }, |
| | | // restore: { show: true }, |
| | | // saveAsImage: { show: true, name: 'å7天å©ç¨çç»è®¡å¾', pixelRatio: 1 } |
| | | // } |
| | | // } |
| | | } |
| | | this.first15DaysEfficiencyChart.setOption(option, true) |
| | | this.first15DaysEfficiencyChart.hideLoading() |
| | | this.first15DaysEfficiencyChart.on('click', params => { |
| | | this.$router.push({ |
| | | name: 'mdc-base-StatisticsChart', |
| | | params: { |
| | | isEquipment: true, |
| | | productionId: params.name, |
| | | tierName: this.first15DaysEfficiencyData.dataList.find(item => item.date === params.name).date |
| | | } |
| | | }) |
| | | }) |
| | | }, |
| | | |
| | | |
| | | /* è°ç¨æ¥å£è·å设å¤OEEç»è®¡ */ |
| | | getBarChartDataByApi(productionCode) { |
| | | this.barChart = this.$echarts.init(document.getElementById('bar_chart')) |
| | | this.barChart.showLoading({ |
| | | text: 'æ°æ®å è½½ä¸ ...', |
| | | color: '#0696e1', // å è½½å¨ç»é¢è² |
| | | textColor: '#fff' |
| | | }) |
| | | signageApi.getEquipmentOEEStatistics(productionCode) |
| | | .then(res => { |
| | | if (res.success && res.result) { |
| | | this.barChartData = res.result |
| | | this.drawBarChart() |
| | | } |
| | | }) |
| | | .finally(() => { |
| | | this.barChart.hideLoading() |
| | | }) |
| | | }, |
| | | |
| | | /* ç»å¶åæ±å¾ */ |
| | | drawBarChart() { |
| | | const defaultData = [] |
| | | const colorArray = ['#79CEAA', '#F589A2', '#6FBF9D', '#66DFE2', '#A7F0C1', '#FAE893', '#F7B7A0'] |
| | | const dataMax = this.barChartData.length > 0 ? +this.barChartData.sort((x, y) => +y.value - +x.value)[0].value : 0 |
| | | let yAxisMax |
| | | if (dataMax === 0) yAxisMax = 1 // è¥æ°æ®ä¸æå¤§å¼ä¸º0ï¼åå°èæ¯é»è®¤å¼è®¾ç½®ä¸º1 |
| | | else yAxisMax = Math.ceil(dataMax / 5) * 5 // 设置æ±å¾èæ¯é´å½±é»è®¤å¼ï¼æè·¯ä¸ºæ°æ®æå¤§å¼ææ¥è¿çè½è¢«5æ´é¤çæ°å |
| | | const yAxisInterval = yAxisMax / 5 // åæ¶å°å»åº¦å¼åæ5份 |
| | | this.barChartData.forEach(item => defaultData.push(yAxisMax)) |
| | | const option = { |
| | | title: { |
| | | show: true, // æ¯å¦æ¾ç¤ºæ é¢ï¼é»è®¤ä¸ºtrue |
| | | text: '', // 主æ é¢ææ¬ |
| | | x: 'left', // æ 颿°´å¹³å®æ¾ä½ç½®ï¼å¯éå¼ä¸º'left'ã'center'ã'right'æå
·ä½çæ°´å¹³åæ å¼ |
| | | y: 'top', // æ é¢åç´å®æ¾ä½ç½®ï¼å¯éå¼ä¸º'top'ã'bottom'ã'center'æå
·ä½çåç´åæ å¼ |
| | | textStyle: { |
| | | // 主æ é¢ææ¬æ ·å¼ |
| | | fontSize: 18, |
| | | fontWeight: 'normal', |
| | | color: '#1AD8DE' |
| | | } |
| | | }, |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'shadow' |
| | | }, |
| | | formatter: function(params) { |
| | | return '<span style="font-weight:bolder;">' + params[0].name + '</span><br/>' + |
| | | '<span style="display:inline-block; width:10px; height:10px; border-radius:100px; margin-right:5px; background:' + params[0].color + '"></span>' + ' OEE: ' + params[0].value + '%' |
| | | }, |
| | | // backgroundColor: 'rgba(9, 24, 48, 0.5)', |
| | | borderColor: 'rgba(75, 253, 238, 0.4)', |
| | | textStyle: { |
| | | // color: '#CFE3FC' |
| | | }, |
| | | borderWidth: 1 |
| | | }, |
| | | grid: { |
| | | top: '20%', |
| | | left: '10%' |
| | | }, |
| | | xAxis: [{ |
| | | name: '', |
| | | nameLocation: 'middle', |
| | | nameGap: 40, // xè½´name䏿¨ªåæ 轴线çé´è· |
| | | type: 'category', |
| | | data: this.barChartData.map(item => item.productionId), |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#000000' |
| | | } |
| | | }, |
| | | axisLabel: { |
| | | show: true, // æ¯å¦æ¾ç¤ºå»åº¦æ ç¾ï¼é»è®¤æ¾ç¤º |
| | | interval: 0, // åæ è½´å»åº¦æ ç¾çæ¾ç¤ºé´éï¼å¨ç±»ç®è½´ä¸ææï¼é»è®¤ä¼éç¨æ ç¾ä¸éå ççç¥é´éæ¾ç¤ºæ ç¾ï¼å¯ä»¥è®¾ç½®æ0å¼ºå¶æ¾ç¤ºæææ ç¾ï¼å¦æè®¾ç½®ä¸º1ï¼è¡¨ç¤ºãéä¸ä¸ªæ ç¾æ¾ç¤ºä¸ä¸ªæ ç¾ãï¼å¦æå¼ä¸º2ï¼è¡¨ç¤ºé两个æ ç¾æ¾ç¤ºä¸ä¸ªæ ç¾ï¼ä»¥æ¤ç±»æ¨ã |
| | | rotate: this.barChartData.length >= 6 ? -30 : 0, // å»åº¦æ ç¾æè½¬çè§åº¦ï¼å¨ç±»ç®è½´çç±»ç®æ ç¾æ¾ç¤ºä¸ä¸çæ¶åå¯ä»¥éè¿æè½¬é²æ¢æ ç¾ä¹é´éå ï¼æè½¬çè§åº¦ä»-90度å°90度 |
| | | inside: false, // å»åº¦æ ç¾æ¯å¦æå
ï¼é»è®¤æå¤ |
| | | margin: 10, // å»åº¦æ ç¾ä¸è½´çº¿ä¹é´çè·ç¦» |
| | | formatter: value => { |
| | | return `${this.barChartData.find(item => item.productionId === value).name}` |
| | | }, |
| | | fontSize: 14 |
| | | }, |
| | | axisTick: { |
| | | show: true, |
| | | alignWithLabel: true |
| | | } |
| | | }], |
| | | yAxis: [{ |
| | | name: '%', |
| | | min: 0, |
| | | max: yAxisMax, |
| | | interval: yAxisInterval, |
| | | axisLabel: { |
| | | formatter: '{value}', |
| | | color: '#000000', |
| | | fontSize: 14 |
| | | }, |
| | | axisTick: { |
| | | show: false |
| | | }, |
| | | axisLine: { |
| | | show: false, |
| | | lineStyle: { |
| | | color: '#000000' |
| | | } |
| | | }, |
| | | splitLine: { |
| | | show: false, |
| | | lineStyle: { |
| | | color: 'rgba(255,255,255,0.12)' |
| | | } |
| | | } |
| | | }], |
| | | series: [{ |
| | | type: 'bar', |
| | | data: this.barChartData, |
| | | barWidth: this.barChartData.length > 5 ? '40%' : 30, |
| | | itemStyle: { |
| | | color: function(params) { |
| | | let num = colorArray.length |
| | | return colorArray[params.dataIndex % num] |
| | | }, |
| | | barBorderRadius: 100 |
| | | }, |
| | | zlevel: 1, |
| | | label: { |
| | | show: false, |
| | | lineHeight: 10, |
| | | formatter: params => { |
| | | if (+params.value === 0) return '' |
| | | else return params.value |
| | | }, |
| | | position: 'top', |
| | | textStyle: { |
| | | color: '#000000', |
| | | fontSize: 16 |
| | | } |
| | | } |
| | | }] |
| | | } |
| | | option.title.text = moment().subtract(1, 'month').format('Mæ') + `OEE` |
| | | this.barChart.setOption(option, true) |
| | | }, |
| | | |
| | | /* ç»å¶è®¾å¤è¿è¡ç¶æç«ç°é¥¼å¾ */ |
| | | drawRunningStateChart() { |
| | | const option = { |
| | | height: 300, |
| | | title: { |
| | | show: true, // æ¯å¦æ¾ç¤ºæ é¢ï¼é»è®¤ä¸ºtrue |
| | | text: '设å¤ç¶æ', // 主æ é¢ææ¬ |
| | | x: 'left', // æ 颿°´å¹³å®æ¾ä½ç½®ï¼å¯éå¼ä¸º'left'ã'center'ã'right'æå
·ä½çæ°´å¹³åæ å¼ |
| | | y: 'top', // æ é¢åç´å®æ¾ä½ç½®ï¼å¯éå¼ä¸º'top'ã'bottom'ã'center'æå
·ä½çåç´åæ å¼ |
| | | textStyle: { |
| | | // 主æ é¢ææ¬æ ·å¼ |
| | | fontSize: 18, |
| | | fontWeight: 'normal', |
| | | color: '#1AD8DE' |
| | | } |
| | | }, |
| | | tooltip: { |
| | | trigger: 'item', |
| | | formatter: function(params) { |
| | | return '<span style="font-weight:bolder;">' + params.name + '</span><br/>' + |
| | | '<span style="display:inline-block; width:10%; height:10%; border-radius:100px; margin-right:5px; background:' + params.color + '"></span>' + `${params.value}ï¼${params.percent}%ï¼` |
| | | } |
| | | }, |
| | | legend: { |
| | | top: 'auto', |
| | | left: 'center', |
| | | bottom: '10%', // åºé¨è·ç¦» |
| | | orient: 'horizontal', // æ°´å¹³æå |
| | | right: '10%', |
| | | // bottom: "0", |
| | | itemWidth: 14, |
| | | itemHeight: 14, |
| | | icon: 'roundRect', |
| | | itemGap: 15, |
| | | textStyle: { |
| | | color: '#000', |
| | | fontSize: 14, |
| | | padding: [0, 0, 0, 0] |
| | | }, |
| | | data: ['å
³æº', 'æ¥è¦', 'å¾
æº', 'è¿è¡'] |
| | | }, |
| | | grid: { |
| | | containLabel: true |
| | | }, |
| | | series: [ |
| | | { |
| | | type: 'pie', |
| | | roseType: 'angle', // ç«ç°å¾ |
| | | // selectedMode: "single", |
| | | radius: this.pieChartRadius, |
| | | center: ['45%', '55%'], |
| | | color: [ |
| | | '#8B8B8B', |
| | | '#F56436', |
| | | '#FFFF40', |
| | | '#0FC61A' |
| | | ], |
| | | label: { |
| | | position: 'outside', |
| | | show: true, |
| | | color: '#000', |
| | | // textBorderColor: 'inherit', |
| | | // textBorderWidth: 1, |
| | | fontSize: 16, |
| | | formatter: function(params) { |
| | | if (params.name !== '') { |
| | | return `${params.name}:${params.value}` |
| | | } |
| | | } |
| | | }, |
| | | labelLine: { |
| | | show: true, |
| | | length2: 10, |
| | | length: 10 |
| | | }, |
| | | data: this.runningStateData |
| | | } |
| | | ] |
| | | } |
| | | this.runningStateChart.setOption(option, true) |
| | | this.runningStateChart.hideLoading() |
| | | }, |
| | | |
| | | /* ç»å¶è®¾å¤å©ç¨çè¶åå¾ */ |
| | | drawEfficiencyChart() { |
| | | const data = this.efficiencyData || [] |
| | | |
| | | // æ è®ºæ°æ®æ¯å¦ä¸ºç©ºï¼å
åæ¶loadingç¶æ |
| | | this.efficiencyChart.hideLoading() |
| | | |
| | | // æ 颿æ¬ç»ä¸å¤ç |
| | | const titleText = `${moment().subtract(1, 'days').format('MæDæ¥')}å车é´å©ç¨çæè¡` |
| | | |
| | | if (data.length === 0) { |
| | | // æ°æ®ä¸ºç©ºæ¶åªå±ç¤ºæ é¢ |
| | | const option = { |
| | | title: { |
| | | show: true, |
| | | text: titleText, |
| | | x: 'left', |
| | | y: 'top', |
| | | textStyle: { |
| | | fontSize: 18, |
| | | fontWeight: 'normal', |
| | | color: '#1AD8DE' |
| | | } |
| | | }, |
| | | // éèææè½´åç½æ ¼ |
| | | xAxis: { show: false }, |
| | | yAxis: [{ show: false }, { show: false }], |
| | | grid: { show: false }, |
| | | series: [] |
| | | } |
| | | this.efficiencyChart.setOption(option, true) |
| | | return |
| | | } |
| | | |
| | | // æ°æ®ä¸ä¸ºç©ºæ¶çæ£å¸¸å¤çé»è¾ï¼ä¿æä¸åï¼ |
| | | const colorArray = [ |
| | | { top: '#79CEAA', bottom: '#79CEAA' }, |
| | | { top: '#F589A2', bottom: '#F589A2' }, |
| | | { top: '#6FBF9D', bottom: '#6FBF9D' }, |
| | | { top: '#66DFE2', bottom: '#66DFE2' }, |
| | | { top: '#A7F0C1', bottom: '#A7F0C1' }, |
| | | { top: '#FAE893', bottom: '#FAE893' }, |
| | | { top: '#F7B7A0', bottom: '#F7B7A0' } |
| | | ] |
| | | |
| | | const dataMax = +data.sort((x, y) => +y.value - +x.value)[0].value |
| | | let yAxisMax = dataMax === 0 ? 1 : Math.ceil(dataMax / 5) * 5 |
| | | const yAxisInterval = yAxisMax / 5 |
| | | |
| | | const option = { |
| | | title: { |
| | | show: true, |
| | | text: titleText, |
| | | x: 'left', |
| | | y: 'top', |
| | | textStyle: { |
| | | fontSize: 18, |
| | | fontWeight: 'normal', |
| | | color: '#1AD8DE' |
| | | } |
| | | }, |
| | | grid: { |
| | | left: '3%', |
| | | right: '5%', |
| | | bottom: '0%', |
| | | top: '6%', |
| | | containLabel: true |
| | | }, |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { type: 'none' }, |
| | | formatter: function(params) { |
| | | return `<span style="font-weight:bolder;">${params[0].name}</span><br/> |
| | | <span style="display:inline-block; width:10px; height:10px; border-radius:100px; margin-right:5px; background:${params[0].color.colorStops[params[0].dataIndex].color}"></span> |
| | | ${params[0].seriesName} : ${params[0].value}%` |
| | | } |
| | | }, |
| | | xAxis: { |
| | | name: '', |
| | | nameTextStyle: { color: '#000000' }, |
| | | axisLabel: { |
| | | margin: 20, |
| | | textStyle: { color: '#000000' } |
| | | }, |
| | | show: true, |
| | | min: 0, |
| | | max: 'dataMax', |
| | | interval: yAxisInterval, |
| | | type: 'value', |
| | | axisTick: { show: false }, |
| | | splitLine: { show: false } |
| | | }, |
| | | yAxis: [{ |
| | | type: 'category', |
| | | inverse: true, |
| | | triggerEvent: true, |
| | | axisLabel: { |
| | | show: true, |
| | | textStyle: { color: '#000000', fontSize: '14', fontWeight: 'bolder' }, |
| | | formatter: function(value) { |
| | | return `${data.find(item => item.productionCode === value).name}` |
| | | } |
| | | }, |
| | | splitLine: { show: false }, |
| | | axisTick: { show: false }, |
| | | axisLine: { show: false }, |
| | | data: data.map(item => item.productionCode) |
| | | }, { |
| | | type: 'category', |
| | | inverse: true, |
| | | axisTick: 'none', |
| | | axisLine: 'none', |
| | | show: true, |
| | | axisLabel: { |
| | | textStyle: { color: '#000000', fontSize: '14' }, |
| | | formatter: '{value}%' |
| | | }, |
| | | data: data |
| | | }], |
| | | series: [{ |
| | | name: 'å©ç¨ç', |
| | | type: 'bar', |
| | | zlevel: 1, |
| | | itemStyle: { |
| | | barBorderRadius: 100, |
| | | color: function(params) { |
| | | const num = colorArray.length |
| | | return { |
| | | type: 'linear', |
| | | colorStops: [{ |
| | | offset: 0, |
| | | color: colorArray[params.dataIndex % num].bottom |
| | | }, { |
| | | offset: 1, |
| | | color: colorArray[params.dataIndex % num].top |
| | | }] |
| | | } |
| | | } |
| | | }, |
| | | barWidth: 12, |
| | | data: data |
| | | }] |
| | | } |
| | | |
| | | this.efficiencyChart.setOption(option, true) |
| | | }, |
| | | |
| | | re_drawPieChart() { |
| | | const clientWidth = document.body.clientWidth || document.documentElement.clientWidth |
| | | if (this.firstEnterClientWidth != 1920) { |
| | | this.pieChartRadius = this.normalPieChartRadius.map(item => item = (+item.slice(0, -1) * (clientWidth / 1920)) + '%') |
| | | } else { |
| | | this.pieChartRadius = this.normalPieChartRadius.map(item => item = (+item.slice(0, -1) * (clientWidth / this.firstEnterClientWidth)) + '%') |
| | | } |
| | | console.log('pieChartRadius', this.pieChartRadius) |
| | | }, |
| | | |
| | | |
| | | /* è°ç¨æ¥å£è·å设å¤OEEåå©ç¨çå¯¹æ¯ */ |
| | | getDoubleBarChartDataByApi(productionCode) { |
| | | this.doubleBarChart = this.$echarts.init(document.getElementById('double_bar_chart')) |
| | | this.doubleBarChart.showLoading({ |
| | | text: 'æ°æ®å è½½ä¸ ...', |
| | | color: '#0696e1', // å è½½å¨ç»é¢è² |
| | | textColor: '#000000', |
| | | maskColor: 'transparent' // é®ç½©å± |
| | | }) |
| | | signageApi.getEquipmentMonthStatisticsApi(productionCode) |
| | | .then(res => { |
| | | if (res.success) { |
| | | this.doubleBarChartData = res.result |
| | | this.drawDoubleBarChart() |
| | | } |
| | | }) |
| | | }, |
| | | /* ç»å¶åæ±å¾ */ |
| | | drawDoubleBarChart() { |
| | | const option = { |
| | | title: { |
| | | text: 'æå©ç¨çOEEç»è®¡', |
| | | left: 'left', |
| | | top: 'top', |
| | | textStyle: { |
| | | fontSize: 18, |
| | | fontWeight: 'normal', |
| | | color: '#1AD8DE' |
| | | } |
| | | }, |
| | | color: ['#66DFE2', '#79CEAA'], |
| | | tooltip: { |
| | | confine: true, |
| | | formatter: function(params) { |
| | | return '<span style="font-weight:bolder;">' + params.name + '</span><br/>' + |
| | | '<span style="display:inline-block; width:10px; height:10px; border-radius:100px; margin-right:5px; background:' + params.color + '"></span>' + params.seriesName + ' : ' + params.value + '%' |
| | | } |
| | | }, |
| | | grid: { |
| | | left: '5%', |
| | | right: '4%', |
| | | bottom: '10%', |
| | | top: '20%', |
| | | containLabel: true |
| | | }, |
| | | legend: { |
| | | icon: 'roundRect', |
| | | orient: 'horizontal', |
| | | left: 'center', |
| | | itemWidth: 14, |
| | | itemHeight: 14, |
| | | formatter: ['{a|{name}}'].join('\n'), |
| | | textStyle: { |
| | | fontSize: 14, |
| | | color: '#000000', |
| | | height: 8, |
| | | rich: { |
| | | a: { |
| | | verticalAlign: 'bottom' |
| | | } |
| | | } |
| | | }, |
| | | data: ['OEE', 'TEEP'] |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: this.doubleBarChartData.dateList, |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: 'rgba(0,0,0)' |
| | | } |
| | | }, |
| | | axisLabel: { |
| | | fontSize: 14, |
| | | color: '#000000' |
| | | }, |
| | | axisTick: { |
| | | show: true |
| | | } |
| | | }, |
| | | yAxis: [ |
| | | { |
| | | name: '%', |
| | | nameTextStyle: { |
| | | color: '#000000' |
| | | }, |
| | | type: 'value', |
| | | min: 0, |
| | | minInterval: 1, |
| | | axisLine: { |
| | | show: true |
| | | }, |
| | | axisTick: { |
| | | show: true |
| | | }, |
| | | splitLine: { |
| | | show: false, |
| | | lineStyle: { |
| | | color: 'rgba(255, 255, 255, 0.15)' |
| | | // type: 'dashed', // dotted è线 |
| | | } |
| | | }, |
| | | axisLabel: { |
| | | fontSize: 14, |
| | | color: '#000000', |
| | | fontFamily: 'Bebas' |
| | | } |
| | | }, |
| | | { |
| | | type: 'value', |
| | | axisLine: { |
| | | show: true |
| | | }, |
| | | axisTick: { |
| | | show: false |
| | | }, |
| | | splitLine: { |
| | | show: false |
| | | }, |
| | | axisLabel: { |
| | | fontSize: 14, |
| | | formatter: '{value}%', // å³ä¾§Yè½´æåæ¾ç¤º |
| | | fontFamily: 'Bebas', |
| | | color: '#6A93B9' |
| | | }, |
| | | splitArea: { |
| | | show: false |
| | | } |
| | | }], |
| | | series: [{ |
| | | type: 'bar', |
| | | barWidth: 15, |
| | | itemStyle: { barBorderRadius: 100 }, |
| | | name: 'OEE', |
| | | data: this.doubleBarChartData.oeeList, |
| | | label: { |
| | | show: false, |
| | | lineHeight: 10, |
| | | formatter: params => { |
| | | if (+params.value === 0) return '' |
| | | else return params.value |
| | | }, |
| | | position: 'inside', |
| | | textStyle: { |
| | | color: '#000000', |
| | | fontSize: 12 |
| | | } |
| | | } |
| | | }, { |
| | | type: 'bar', |
| | | barWidth: 15, |
| | | itemStyle: { barBorderRadius: 100 }, |
| | | name: 'TEEP', |
| | | data: this.doubleBarChartData.utilizationList, |
| | | label: { |
| | | show: false, |
| | | lineHeight: 10, |
| | | formatter: params => { |
| | | if (+params.value === 0) return '' |
| | | else return params.value |
| | | }, |
| | | position: 'inside', |
| | | textStyle: { |
| | | color: '#000000', |
| | | fontSize: 12 |
| | | } |
| | | } |
| | | } |
| | | ] |
| | | } |
| | | this.doubleBarChart.setOption(option, true) |
| | | this.doubleBarChart.hideLoading() |
| | | }, |
| | | |
| | | /** |
| | | * çªå£å°ºå¯¸ååæ¶è§¦å |
| | | * è°æ´å¾è¡¨å°ºå¯¸ä»¥éåºå辨ç |
| | | */ |
| | | handleWindowResize() { |
| | | // this.re_drawPieChart() |
| | | if (this.runningStateChart) this.runningStateChart.resize() |
| | | if (this.efficiencyChart) this.efficiencyChart.resize() |
| | | if (this.first15DaysEfficiencyChart) this.first15DaysEfficiencyChart.resize() |
| | | if (this.barChart) this.barChart.resize() |
| | | if (this.doubleBarChart) this.doubleBarChart.resize() |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | /* 页ç¾å¯¼èªæ ·å¼ */ |
| | | .tab-nav { |
| | | display: flex; |
| | | gap: 8px; |
| | | padding: 10px 16px; |
| | | background-color: #ffffff; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); |
| | | overflow-x: auto; |
| | | scrollbar-width: none; |
| | | } |
| | | |
| | | .tab-nav::-webkit-scrollbar { |
| | | display: none; |
| | | } |
| | | |
| | | .tab-item { |
| | | padding: 8px 16px; |
| | | font-size: 14px; |
| | | color: #666666; |
| | | border-radius: 20px; |
| | | cursor: pointer; |
| | | white-space: nowrap; |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .tab-active { |
| | | background-color: #0696e1; |
| | | color: #ffffff; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .tab-item:hover { |
| | | background-color: #f0f5ff; |
| | | color: #0696e1; |
| | | } |
| | | |
| | | /* 䏻容卿 ·å¼ */ |
| | | .home-container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | min-height: 100vh; |
| | | padding: 1px; |
| | | box-sizing: border-box; |
| | | gap: 16px; |
| | | background-color: #f0f2f7; |
| | | } |
| | | |
| | | /* å¾è¡¨å®¹å¨æ ·å¼ */ |
| | | .chart-container { |
| | | display: flex; |
| | | gap: 16px; |
| | | flex: 1; |
| | | min-width: 0; |
| | | } |
| | | |
| | | /* 左侧å¡çåºå */ |
| | | .left-cards { |
| | | flex: 1; |
| | | min-width: 0; |
| | | } |
| | | |
| | | /* å³ä¾§å¡çåºå */ |
| | | .right-cards { |
| | | flex: 2; |
| | | min-width: 0; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 16px; |
| | | } |
| | | |
| | | /* éç¨å¡çæ ·å¼ */ |
| | | .card { |
| | | background: #ffffff; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); |
| | | padding: 16px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | overflow: hidden; |
| | | justify-content: flex-start; |
| | | } |
| | | |
| | | /* 左侧å¡ç */ |
| | | .left-cards-card { |
| | | height: 100%; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | /* å³ä¾§é¡¶é¨å¡ç */ |
| | | .right-top-card { |
| | | flex: 1; |
| | | min-height: 50vh; |
| | | } |
| | | |
| | | /* å³ä¾§åºé¨å®¹å¨ */ |
| | | .right-bottom-card { |
| | | flex: 1; |
| | | min-width: 0; |
| | | min-height: 50vh; |
| | | display: flex; |
| | | gap: 16px; |
| | | } |
| | | |
| | | /* å³ä¾§åºé¨å·¦å³å¡ç */ |
| | | .right-bottom-left-card, |
| | | .right-bottom-right-card { |
| | | flex: 1; |
| | | } |
| | | |
| | | /* ååºå¼è°æ´ */ |
| | | @media (max-width: 1200px) { |
| | | .chart-container { |
| | | gap: 12px; |
| | | } |
| | | |
| | | .card { |
| | | padding: 12px; |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 992px) { |
| | | .chart-container { |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .left-cards, .right-cards { |
| | | width: 100%; |
| | | } |
| | | |
| | | .left-cards { |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .right-bottom-card { |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .tab-item { |
| | | padding: 6px 12px; |
| | | font-size: 13px; |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 768px) { |
| | | .home-container { |
| | | padding: 8px; |
| | | } |
| | | |
| | | .tab-nav { |
| | | padding: 8px; |
| | | margin-bottom: 8px; |
| | | } |
| | | } |
| | | </style> |