test #47
@@ -96,18 +96,7 @@ export default class GanttGraph {
 | 
			
		||||
        this.currentGraphIndex = -2;
 | 
			
		||||
        this.startTime = new Date(startTime);
 | 
			
		||||
        // this.startTime = new Date(new Date('2023/10/8').toLocaleDateString());
 | 
			
		||||
        console.log('<> Gantt Created', this.startTime);
 | 
			
		||||
 | 
			
		||||
        // this.grid.push(this.makeGrid())
 | 
			
		||||
        // this.xAxis.push(...this.makeXaxis())
 | 
			
		||||
        // this.yAxis.push(...this.makeYaxis("设备1"))
 | 
			
		||||
        // this.series.push(...this.makeSeries({ equipmentName: "设备1" }))
 | 
			
		||||
 | 
			
		||||
        // this.grid.push(this.makeGrid())
 | 
			
		||||
        // this.xAxis.push(...this.makeXaxis())
 | 
			
		||||
        // this.yAxis.push(...this.makeYaxis("设备2"))
 | 
			
		||||
        // this.series.push(...this.makeSeries({ equipmentName: "设备2" }))
 | 
			
		||||
 | 
			
		||||
        // console.log('<> Gantt Created', this.startTime);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 构造一个新的 grid
 | 
			
		||||
@@ -223,8 +212,8 @@ export default class GanttGraph {
 | 
			
		||||
                        value: [0, bgStartTime, bgEndTime, 0],
 | 
			
		||||
                        tooltip: { show: false },
 | 
			
		||||
                        itemStyle: {
 | 
			
		||||
                            color: '#ccc',
 | 
			
		||||
                            opacity: 0.3,
 | 
			
		||||
                            color: '#F2F4F9',
 | 
			
		||||
                            // opacity: 0.3,
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                ]
 | 
			
		||||
@@ -1,235 +0,0 @@
 | 
			
		||||
import * as echarts from 'echarts';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function renderItem(params, api) {
 | 
			
		||||
    var categoryIndex = api.value(0);
 | 
			
		||||
    var start = api.coord([api.value(1), categoryIndex]);
 | 
			
		||||
    var end = api.coord([api.value(2), categoryIndex]);
 | 
			
		||||
    var height = api.size([0, 1])[1] * 1;
 | 
			
		||||
    // var height = api.size([0, 1])[1] * 0.8;
 | 
			
		||||
    // var height = 56;
 | 
			
		||||
    var rectShape = echarts.graphic.clipRectByRect(
 | 
			
		||||
        {
 | 
			
		||||
            x: start[0],
 | 
			
		||||
            y: start[1] - height / 2,
 | 
			
		||||
            width: end[0] - start[0],
 | 
			
		||||
            height: height,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            x: params.coordSys.x,
 | 
			
		||||
            y: params.coordSys.y,
 | 
			
		||||
            width: params.coordSys.width,
 | 
			
		||||
            height: params.coordSys.height,
 | 
			
		||||
        }
 | 
			
		||||
    );
 | 
			
		||||
    return (
 | 
			
		||||
        rectShape && {
 | 
			
		||||
            type: 'rect',
 | 
			
		||||
            transition: ['shape'],
 | 
			
		||||
            shape: rectShape,
 | 
			
		||||
            style: api.style(),
 | 
			
		||||
        }
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** 颜色配置 */
 | 
			
		||||
const types = [
 | 
			
		||||
    { name: '运行', color: '#5ad8a6' },
 | 
			
		||||
    { name: '故障', color: '#fc9c91' },
 | 
			
		||||
    { name: '计划停机', color: '#000' },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** 从时间戳获取 startTime */
 | 
			
		||||
function getStartTime(timestamp) {
 | 
			
		||||
    return new Date(new Date(timestamp).toLocaleDateString()).getTime();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default class GanttGraph {
 | 
			
		||||
    constructor(el) {
 | 
			
		||||
        this.chart = null;
 | 
			
		||||
        this.el = el;
 | 
			
		||||
        /** 默认配置 */
 | 
			
		||||
        this.grid = {
 | 
			
		||||
            top: 32,
 | 
			
		||||
            left: 128,
 | 
			
		||||
            right: 128,
 | 
			
		||||
            bottom: 64,
 | 
			
		||||
        }
 | 
			
		||||
        this.tooltip = {
 | 
			
		||||
            formatter: function (params) {
 | 
			
		||||
                return (
 | 
			
		||||
                    params.marker +
 | 
			
		||||
                    params.name +
 | 
			
		||||
                    ': ' +
 | 
			
		||||
                    new Date(params.value[1]).toLocaleTimeString() +
 | 
			
		||||
                    ' - ' +
 | 
			
		||||
                    new Date(params.value[2]).toLocaleTimeString()
 | 
			
		||||
                );
 | 
			
		||||
            },
 | 
			
		||||
        }
 | 
			
		||||
        this.xAxis = {
 | 
			
		||||
            type: 'time',
 | 
			
		||||
            min: getStartTime(1691568181000), // <===
 | 
			
		||||
            max: getStartTime(1691568181000 + 3600 * 24 * 1000), // <===
 | 
			
		||||
            splitNumber: 10,
 | 
			
		||||
            axisLabel: {
 | 
			
		||||
                // rotate: -15,
 | 
			
		||||
                formatter: function (val) {
 | 
			
		||||
                    return new Date(val).toLocaleTimeString();
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
            axisTick: {
 | 
			
		||||
                show: true,
 | 
			
		||||
            },
 | 
			
		||||
            splitLine: {
 | 
			
		||||
                show: false,
 | 
			
		||||
            },
 | 
			
		||||
        }
 | 
			
		||||
        this.yAxis = [
 | 
			
		||||
            {
 | 
			
		||||
                interval: 40,
 | 
			
		||||
                axisLine: {
 | 
			
		||||
                    lineStyle: {
 | 
			
		||||
                        color: '',
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
                axisLabel: {
 | 
			
		||||
                    fontSize: 18,
 | 
			
		||||
                },
 | 
			
		||||
                axisTick: {
 | 
			
		||||
                    show: false,
 | 
			
		||||
                },
 | 
			
		||||
                splitLine: {
 | 
			
		||||
                    show: true,
 | 
			
		||||
                },
 | 
			
		||||
                // data: [], // <====
 | 
			
		||||
                data: ['设备1', '设备2', '设备3', '设备4'],
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                axisLine: {
 | 
			
		||||
                    lineStyle: {
 | 
			
		||||
                        color: '',
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
                data: [],
 | 
			
		||||
            },
 | 
			
		||||
        ]
 | 
			
		||||
        this.series = [
 | 
			
		||||
            {
 | 
			
		||||
                type: 'custom',
 | 
			
		||||
                renderItem: renderItem,
 | 
			
		||||
                itemStyle: {
 | 
			
		||||
                    opacity: 0.8,
 | 
			
		||||
                },
 | 
			
		||||
                encode: {
 | 
			
		||||
                    x: [1, 2],
 | 
			
		||||
                    y: 0,
 | 
			
		||||
                },
 | 
			
		||||
                // data: [], // <===
 | 
			
		||||
                data: [
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '运行',
 | 
			
		||||
                        value: [
 | 
			
		||||
                            0,
 | 
			
		||||
                            1691568181000,
 | 
			
		||||
                            1691568181000 + 60 * 60 * 1000,
 | 
			
		||||
                            60 * 10 * 1000,
 | 
			
		||||
                        ],
 | 
			
		||||
                        itemStyle: {
 | 
			
		||||
                            normal: {
 | 
			
		||||
                                color: types[0].color,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '计划停机',
 | 
			
		||||
                        value: [
 | 
			
		||||
                            0,
 | 
			
		||||
                            1691578581000,
 | 
			
		||||
                            1691578581000 + 10 * 60 * 1000,
 | 
			
		||||
                            60 * 10 * 1000,
 | 
			
		||||
                        ],
 | 
			
		||||
                        itemStyle: {
 | 
			
		||||
                            normal: {
 | 
			
		||||
                                color: types[2].color,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '运行',
 | 
			
		||||
                        value: [
 | 
			
		||||
                            1,
 | 
			
		||||
                            1691568181000,
 | 
			
		||||
                            1691568181000 + 60 * 60 * 1000,
 | 
			
		||||
                            60 * 10 * 1000,
 | 
			
		||||
                        ],
 | 
			
		||||
                        itemStyle: {
 | 
			
		||||
                            normal: {
 | 
			
		||||
                                color: types[0].color,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '故障',
 | 
			
		||||
                        value: [
 | 
			
		||||
                            2,
 | 
			
		||||
                            1691538181000,
 | 
			
		||||
                            1691538181000 + 60 * 60 * 1000,
 | 
			
		||||
                            60 * 10 * 1000,
 | 
			
		||||
                        ],
 | 
			
		||||
                        itemStyle: {
 | 
			
		||||
                            normal: {
 | 
			
		||||
                                color: types[1].color,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '运行',
 | 
			
		||||
                        value: [
 | 
			
		||||
                            2,
 | 
			
		||||
                            1691578181000,
 | 
			
		||||
                            1691578181000 + 90 * 60 * 1000,
 | 
			
		||||
                            90 * 10 * 1000,
 | 
			
		||||
                        ],
 | 
			
		||||
                        itemStyle: {
 | 
			
		||||
                            normal: {
 | 
			
		||||
                                color: types[0].color,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '计划停机',
 | 
			
		||||
                        value: [
 | 
			
		||||
                            3,
 | 
			
		||||
                            1691528181000,
 | 
			
		||||
                            1691528181000 + 240 * 60 * 1000,
 | 
			
		||||
                            240 * 10 * 1000,
 | 
			
		||||
                        ],
 | 
			
		||||
                        itemStyle: {
 | 
			
		||||
                            normal: {
 | 
			
		||||
                                color: types[2].color,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
            },
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    init() {
 | 
			
		||||
        this.chart = echarts.init(this.el);
 | 
			
		||||
        this.chart.setOption(this.getOption())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getOption() {
 | 
			
		||||
        const { grid, xAxis, yAxis, series, tooltip } = this;
 | 
			
		||||
        return {
 | 
			
		||||
            grid, xAxis, yAxis, series, tooltip
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,607 +0,0 @@
 | 
			
		||||
<!-- 
 | 
			
		||||
    filename: index.vue
 | 
			
		||||
    author: liubin
 | 
			
		||||
    date: 2023-09-04 09:34:52
 | 
			
		||||
    description: 设备状态时序图
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
	<div
 | 
			
		||||
		class="status-timegraph-container"
 | 
			
		||||
		style="background: #f2f4f9; flex: 1; display: flex; flex-direction: column">
 | 
			
		||||
		<el-row
 | 
			
		||||
			class=""
 | 
			
		||||
			style="
 | 
			
		||||
				margin-bottom: 12px;
 | 
			
		||||
				background: #fff;
 | 
			
		||||
				padding: 16px 16px 0;
 | 
			
		||||
				border-radius: 8px;
 | 
			
		||||
			">
 | 
			
		||||
			<div class="blue-title">生产节拍时序图</div>
 | 
			
		||||
			<!-- <h1>设备状态时序图</h1> -->
 | 
			
		||||
			<!-- 搜索工作栏 -->
 | 
			
		||||
			<SearchBar
 | 
			
		||||
				:formConfigs="searchBarFormConfig"
 | 
			
		||||
				ref="search-bar"
 | 
			
		||||
				:remove-blue="true"
 | 
			
		||||
				@select-changed="handleSearchBarSelectChange"
 | 
			
		||||
				@headBtnClick="handleSearchBarBtnClick" />
 | 
			
		||||
		</el-row>
 | 
			
		||||
 | 
			
		||||
		<el-row
 | 
			
		||||
			class=""
 | 
			
		||||
			style="
 | 
			
		||||
				height: 1px;
 | 
			
		||||
				flex: 1;
 | 
			
		||||
				margin-bottom: 12px;
 | 
			
		||||
				background: #fff;
 | 
			
		||||
				padding: 16px 16px 32px;
 | 
			
		||||
				border-radius: 8px;
 | 
			
		||||
				display: flex;
 | 
			
		||||
				flex-direction: column;
 | 
			
		||||
			">
 | 
			
		||||
			<el-row :gutter="20">
 | 
			
		||||
				<el-col :span="6">
 | 
			
		||||
					<div class="blue-title">设备状态时序图</div>
 | 
			
		||||
				</el-col>
 | 
			
		||||
				<el-col :span="18" class="legend-row">
 | 
			
		||||
					<div class="legend">
 | 
			
		||||
						<div class="icon running"></div>
 | 
			
		||||
						<div>运行中</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					<!-- <div class="legend">
 | 
			
		||||
					<div class="icon waiting"></div>
 | 
			
		||||
					<div>待机</div>
 | 
			
		||||
				</div> -->
 | 
			
		||||
					<div class="legend">
 | 
			
		||||
						<div class="icon fault"></div>
 | 
			
		||||
						<div>故障</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					<!-- <div class="legend">
 | 
			
		||||
					<div class="icon lack"></div>
 | 
			
		||||
					<div>缺料</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="legend">
 | 
			
		||||
					<div class="icon full"></div>
 | 
			
		||||
					<div>满料</div>
 | 
			
		||||
				</div> -->
 | 
			
		||||
					<div class="legend">
 | 
			
		||||
						<div class="icon stop"></div>
 | 
			
		||||
						<div>计划停机</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</el-col>
 | 
			
		||||
			</el-row>
 | 
			
		||||
			<div
 | 
			
		||||
				class="main-area"
 | 
			
		||||
				style="flex: 1; display: flex; flex-direction: column">
 | 
			
		||||
				<div
 | 
			
		||||
					class="graphs"
 | 
			
		||||
					v-show="graphList.length"
 | 
			
		||||
					id="status-chart"
 | 
			
		||||
					style="height: 1px; flex: 1"></div>
 | 
			
		||||
				<h2 v-if="!graphList || graphList.length == 0" class="no-data-bg"></h2>
 | 
			
		||||
			</div>
 | 
			
		||||
		</el-row>
 | 
			
		||||
 | 
			
		||||
		<!-- 对话框(添加 / 修改) -->
 | 
			
		||||
		<base-dialog
 | 
			
		||||
			dialogTitle="添加设备"
 | 
			
		||||
			:dialogVisible="open"
 | 
			
		||||
			width="500px"
 | 
			
		||||
			@close="open = false"
 | 
			
		||||
			@cancel="open = false"
 | 
			
		||||
			@confirm="submitForm">
 | 
			
		||||
			<el-select
 | 
			
		||||
				v-if="open"
 | 
			
		||||
				style="width: 100%"
 | 
			
		||||
				v-model="queryParams.equipmentId"
 | 
			
		||||
				placeholder="请选择一个设备">
 | 
			
		||||
				<el-option
 | 
			
		||||
					v-for="eq in eqList"
 | 
			
		||||
					:key="eq.id"
 | 
			
		||||
					:value="eq.id"
 | 
			
		||||
					:label="eq.name"></el-option>
 | 
			
		||||
			</el-select>
 | 
			
		||||
		</base-dialog>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
// import * as echarts from 'echarts';
 | 
			
		||||
import Gantt from './gantt';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	name: 'SGStatus',
 | 
			
		||||
	components: {},
 | 
			
		||||
	props: {},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			chart: null,
 | 
			
		||||
			searchBarFormConfig: [
 | 
			
		||||
				{
 | 
			
		||||
					type: 'select',
 | 
			
		||||
					label: '产线',
 | 
			
		||||
					placeholder: '请选择产线',
 | 
			
		||||
					selectOptions: [],
 | 
			
		||||
					param: 'lineId',
 | 
			
		||||
					onchange: true,
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'select',
 | 
			
		||||
					label: '工段',
 | 
			
		||||
					placeholder: '请选择工段',
 | 
			
		||||
					selectOptions: [],
 | 
			
		||||
					param: 'sectionId',
 | 
			
		||||
				},
 | 
			
		||||
				// 时间段
 | 
			
		||||
				{
 | 
			
		||||
					type: 'datePicker',
 | 
			
		||||
					label: '时间段',
 | 
			
		||||
					dateType: 'date',
 | 
			
		||||
					format: 'yyyy-MM-dd',
 | 
			
		||||
					valueFormat: 'yyyy-MM-dd HH:mm:ss',
 | 
			
		||||
					rangeSeparator: '-',
 | 
			
		||||
					placeholder: '选择日期',
 | 
			
		||||
					param: 'recordTime',
 | 
			
		||||
					required: true,
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'button',
 | 
			
		||||
					btnName: '查询',
 | 
			
		||||
					name: 'search',
 | 
			
		||||
					color: 'primary',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'separate',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'button',
 | 
			
		||||
					btnName: '添加对比',
 | 
			
		||||
					name: 'compare',
 | 
			
		||||
					color: 'primary',
 | 
			
		||||
					plain: true,
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
			queryParams: {
 | 
			
		||||
				lineId: null,
 | 
			
		||||
				sectionId: null,
 | 
			
		||||
				equipmentId: null,
 | 
			
		||||
				recordTime: null,
 | 
			
		||||
			},
 | 
			
		||||
			graphList: [],
 | 
			
		||||
			open: false,
 | 
			
		||||
			eqList: [],
 | 
			
		||||
			startTime: null,
 | 
			
		||||
			gantt: null
 | 
			
		||||
			// demo: [
 | 
			
		||||
			// 	[
 | 
			
		||||
			// 		{
 | 
			
		||||
			// 			equipmentName: '下片机',
 | 
			
		||||
			// 			duration: 30,
 | 
			
		||||
			// 			relativeDuration: 0.6,
 | 
			
		||||
			// 			status: 0,
 | 
			
		||||
			// 			startPos: 0,
 | 
			
		||||
			//             startTime: 1691568181000,
 | 
			
		||||
			// 		},
 | 
			
		||||
			// 		{
 | 
			
		||||
			// 			equipmentName: '下片机',
 | 
			
		||||
			// 			duration: 20,
 | 
			
		||||
			// 			relativeDuration: 0.4,
 | 
			
		||||
			// 			status: 2,
 | 
			
		||||
			// 			startPos: 30,
 | 
			
		||||
			//             startTime: 1691569981000
 | 
			
		||||
			// 		},
 | 
			
		||||
			// 	],
 | 
			
		||||
			// ],
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	computed: {},
 | 
			
		||||
	created() {
 | 
			
		||||
		this.initProductline();
 | 
			
		||||
		this.initWorksection();
 | 
			
		||||
		this.initEquipment();
 | 
			
		||||
		// this.getList();
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {},
 | 
			
		||||
	watch: {
 | 
			
		||||
		graphList: {
 | 
			
		||||
			handler(val) {
 | 
			
		||||
				if (val && val.length) {
 | 
			
		||||
					this.$nextTick(() => {
 | 
			
		||||
						if (!this.chart) this.initChart();
 | 
			
		||||
						this.setInitialConfig();
 | 
			
		||||
						this.handleGraphList();
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
				return;
 | 
			
		||||
			},
 | 
			
		||||
			deep: true,
 | 
			
		||||
			immediate: true,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		setInitialConfig() {
 | 
			
		||||
			console.log('in setInitialConfig', this.chartOption);
 | 
			
		||||
			this.chart.setOption(this.chartOption);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		handleGraphList() {
 | 
			
		||||
			console.log('in handleGraphList:', this.graphList);
 | 
			
		||||
			return;
 | 
			
		||||
			const min = this.queryParams.recordTime
 | 
			
		||||
				? new Date(this.queryParams.recordTime).getTime()
 | 
			
		||||
				: this.findMin();
 | 
			
		||||
 | 
			
		||||
			console.log('min is', min);
 | 
			
		||||
			this.chartOption.xAxis.min = getStartTime(min);
 | 
			
		||||
			this.chartOption.xAxis.max = getStartTime(min + 3600 * 24 * 1000);
 | 
			
		||||
			this.graphList.forEach((arr) => {
 | 
			
		||||
				this.chartOption.yAxis[0].data.push(arr.key);
 | 
			
		||||
				arr.forEach((item) => {
 | 
			
		||||
					this.chartOption.series[0].data.push({
 | 
			
		||||
						name: ['运行', '故障', '计划停机'][item.status],
 | 
			
		||||
						value: [
 | 
			
		||||
							0,
 | 
			
		||||
							item.startTime,
 | 
			
		||||
							item.startTime + item.duration * 60 * 1000,
 | 
			
		||||
							item.duration * 60 * 1000,
 | 
			
		||||
						],
 | 
			
		||||
						itemStyle: {
 | 
			
		||||
							normal: {
 | 
			
		||||
								color: types[item.status].color,
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					});
 | 
			
		||||
				});
 | 
			
		||||
				console.log('chartOptions', this.chartOption);
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		findMin() {
 | 
			
		||||
			let min = 0;
 | 
			
		||||
			this.graphList.forEach((arr) => {
 | 
			
		||||
				arr.forEach((item) => {
 | 
			
		||||
					if (min < item.startTime) min = item.startTime;
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
			return min;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		initChart() {
 | 
			
		||||
			const el = document.getElementById('status-chart');
 | 
			
		||||
			this.gantt = new Gantt(el);
 | 
			
		||||
			this.gantt.init();
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/** 重置查询条件 */
 | 
			
		||||
		initQuery() {
 | 
			
		||||
			this.queryParams.lineId = null;
 | 
			
		||||
			this.queryParams.equipmentId = null;
 | 
			
		||||
			this.queryParams.sectionId = null;
 | 
			
		||||
			this.queryParams.recordTime = null;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/** 对象到数组的转换 */
 | 
			
		||||
		objectToArray(obj) {
 | 
			
		||||
			return Object.keys(obj).map((key) => {
 | 
			
		||||
				obj[key].sort((a, b) => a.startTime - b.startTime);
 | 
			
		||||
				obj[key].key = key;
 | 
			
		||||
				return obj[key];
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		async getList() {
 | 
			
		||||
			const { code, data } = await this.$axios({
 | 
			
		||||
				url: '/analysis/equipment-analysis/status',
 | 
			
		||||
				method: 'get',
 | 
			
		||||
				params: this.queryParams,
 | 
			
		||||
			});
 | 
			
		||||
			if (code == 0) {
 | 
			
		||||
				this.graphList = this.objectToArray(data);
 | 
			
		||||
				console.log('graph list', this.graphList);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/** 准备设备数据 */
 | 
			
		||||
		async initEquipment() {
 | 
			
		||||
			const { code, data } = await this.$axios({
 | 
			
		||||
				url: '/base/equipment/listAll',
 | 
			
		||||
				method: 'get',
 | 
			
		||||
			});
 | 
			
		||||
			if (code == 0) {
 | 
			
		||||
				this.eqList = data.map((item) => {
 | 
			
		||||
					return {
 | 
			
		||||
						name: item.name,
 | 
			
		||||
						id: item.id,
 | 
			
		||||
					};
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/** 准备产线数据 */
 | 
			
		||||
		async initProductline() {
 | 
			
		||||
			const { code, data } = await this.$axios({
 | 
			
		||||
				url: '/base/production-line/listAll',
 | 
			
		||||
				method: 'get',
 | 
			
		||||
			});
 | 
			
		||||
			if (code == 0) {
 | 
			
		||||
				this.searchBarFormConfig[0].selectOptions = data.map((item) => {
 | 
			
		||||
					return {
 | 
			
		||||
						name: item.name,
 | 
			
		||||
						id: item.id,
 | 
			
		||||
					};
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/** 准备工段数据 */
 | 
			
		||||
		async initWorksection() {
 | 
			
		||||
			const { code, data } = await this.$axios({
 | 
			
		||||
				url: '/base/workshop-section/listAll',
 | 
			
		||||
				method: 'get',
 | 
			
		||||
			});
 | 
			
		||||
			if (code == 0) {
 | 
			
		||||
				this.searchBarFormConfig[1].selectOptions = data.map((item) => {
 | 
			
		||||
					return {
 | 
			
		||||
						name: item.name,
 | 
			
		||||
						id: item.id,
 | 
			
		||||
					};
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		handleSearchBarSelectChange({ param, value }) {
 | 
			
		||||
			if (!value) {
 | 
			
		||||
				this.searchBarFormConfig[1].selectOptions = [];
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			switch (param) {
 | 
			
		||||
				case 'lineId':
 | 
			
		||||
					this.$axios({
 | 
			
		||||
						url: '/base/workshop-section/listByParentId',
 | 
			
		||||
						method: 'get',
 | 
			
		||||
						params: {
 | 
			
		||||
							id: value,
 | 
			
		||||
						},
 | 
			
		||||
					}).then(({ code, data }) => {
 | 
			
		||||
						if (code == 0) {
 | 
			
		||||
							this.searchBarFormConfig[1].selectOptions = data.map((item) => {
 | 
			
		||||
								return {
 | 
			
		||||
									name: item.name,
 | 
			
		||||
									id: item.id,
 | 
			
		||||
								};
 | 
			
		||||
							});
 | 
			
		||||
						}
 | 
			
		||||
					});
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		handleSearchBarBtnClick({ btnName, ...payload }) {
 | 
			
		||||
			switch (btnName) {
 | 
			
		||||
				case 'search':
 | 
			
		||||
					if (!payload.recordTime || payload.recordTime.length <= 0) {
 | 
			
		||||
						this.$message.error('请选择时间段');
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					this.startTime = new Date(payload.recordTime).getTime();
 | 
			
		||||
 | 
			
		||||
					this.queryParams.lineId = payload.lineId || null;
 | 
			
		||||
					this.queryParams.sectionId = payload.sectionId || null;
 | 
			
		||||
					this.queryParams.equipmentId = payload.equipmentId || null;
 | 
			
		||||
					this.queryParams.recordTime = payload.recordTime
 | 
			
		||||
						? [
 | 
			
		||||
								payload.recordTime,
 | 
			
		||||
								new Date(
 | 
			
		||||
									new Date(payload.recordTime).getTime() + 24 * 3600 * 1000
 | 
			
		||||
								)
 | 
			
		||||
									.toLocaleDateString()
 | 
			
		||||
									.split('/')
 | 
			
		||||
									.map((value, index) => {
 | 
			
		||||
										if (index == 1 || index == 2) {
 | 
			
		||||
											return value.padStart(2, '0');
 | 
			
		||||
										}
 | 
			
		||||
										return value;
 | 
			
		||||
									})
 | 
			
		||||
									.join('-') + ' 00:00:00',
 | 
			
		||||
						  ]
 | 
			
		||||
						: null;
 | 
			
		||||
					this.getList();
 | 
			
		||||
					break;
 | 
			
		||||
				case 'compare':
 | 
			
		||||
					this.open = true;
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		async submitForm() {
 | 
			
		||||
			const { code, data } = await this.$axios({
 | 
			
		||||
				url: '/analysis/equipment-analysis/status',
 | 
			
		||||
				method: 'get',
 | 
			
		||||
				params: this.queryParams,
 | 
			
		||||
			});
 | 
			
		||||
			if (code == 0) {
 | 
			
		||||
				const newEqlist = this.objectToArray(data);
 | 
			
		||||
				if (!newEqlist || newEqlist.length == 0) {
 | 
			
		||||
					this.$message.error('该设备没有状态数据');
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				this.graphList.push(newEqlist[0]);
 | 
			
		||||
			}
 | 
			
		||||
			this.open = false;
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
.graph {
 | 
			
		||||
	// border: 1px solid #ccc;
 | 
			
		||||
	// padding: 12px 12px 28px 12px;
 | 
			
		||||
	// margin: 64px 0;
 | 
			
		||||
	position: relative;
 | 
			
		||||
	display: flex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graph-title {
 | 
			
		||||
	// position: absolute;
 | 
			
		||||
	// top: -64px;
 | 
			
		||||
	// left: -1px;
 | 
			
		||||
	// padding: 8px 18px;
 | 
			
		||||
	padding: 0 12px;
 | 
			
		||||
	font-size: 14px;
 | 
			
		||||
	line-height: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graph-content {
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex: 1;
 | 
			
		||||
	padding: 22px 12px;
 | 
			
		||||
	border: 1px solid #ccc;
 | 
			
		||||
	border-bottom-width: 2px;
 | 
			
		||||
	border-top: none;
 | 
			
		||||
	position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graph-content::after,
 | 
			
		||||
.graph-content::before {
 | 
			
		||||
	content: '';
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	width: 3px;
 | 
			
		||||
	height: 80%;
 | 
			
		||||
	background: #fff;
 | 
			
		||||
	right: -1px;
 | 
			
		||||
	top: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graph-content::before {
 | 
			
		||||
	right: unset;
 | 
			
		||||
	left: -1px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graph-item,
 | 
			
		||||
.graph-item-fixed {
 | 
			
		||||
	// height: 88px;
 | 
			
		||||
	// width: 24px;
 | 
			
		||||
	flex: 1;
 | 
			
		||||
	// border: 1px solid #ccc;
 | 
			
		||||
	position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graph-item-fixed {
 | 
			
		||||
	flex: unset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graph-item::before,
 | 
			
		||||
.graph-item-fixed::before {
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	bottom: -16px;
 | 
			
		||||
	left: 0;
 | 
			
		||||
	content: attr(data-time);
 | 
			
		||||
	// font-size - js
 | 
			
		||||
	// rotate - js
 | 
			
		||||
	// color - js, default:
 | 
			
		||||
	color: #777;
 | 
			
		||||
	transform-origin: left top;
 | 
			
		||||
	transform: rotate(12deg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graph-item-fixed::after,
 | 
			
		||||
.graph-item::after {
 | 
			
		||||
	content: '';
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	left: 0;
 | 
			
		||||
	bottom: -3px;
 | 
			
		||||
	display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graph-item.tick::after,
 | 
			
		||||
.graph-item-fixed.tick::after {
 | 
			
		||||
	width: 1px;
 | 
			
		||||
	height: 6px;
 | 
			
		||||
	border-left: 1px solid #777;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.running {
 | 
			
		||||
	background-color: #5ad8a6;
 | 
			
		||||
	// background-color: #84f04e;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.waiting {
 | 
			
		||||
	background-color: #5ad8a6;
 | 
			
		||||
	// background-color: #409eff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.fault {
 | 
			
		||||
	// background-color: #ea5b5b;
 | 
			
		||||
	background-color: #fc9c91;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.full {
 | 
			
		||||
	// background-color: #e6a23c;
 | 
			
		||||
	background-color: #598fff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lack {
 | 
			
		||||
	// background-color: #a69c8d;
 | 
			
		||||
	background-color: #7585a2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.stop {
 | 
			
		||||
	background-color: #000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.legend-row {
 | 
			
		||||
	margin: 6px 0;
 | 
			
		||||
	padding-right: 12px;
 | 
			
		||||
	display: flex;
 | 
			
		||||
	justify-content: flex-end;
 | 
			
		||||
 | 
			
		||||
	> .legend:not(:last-child) {
 | 
			
		||||
		margin-right: 12px;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	.legend {
 | 
			
		||||
		display: flex;
 | 
			
		||||
		align-items: center;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	.icon {
 | 
			
		||||
		width: 8px;
 | 
			
		||||
		height: 8px;
 | 
			
		||||
		border-radius: 2px;
 | 
			
		||||
		margin-right: 4px;
 | 
			
		||||
		margin-top: 1px;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.blue-title {
 | 
			
		||||
	position: relative;
 | 
			
		||||
	padding: 4px 0;
 | 
			
		||||
	padding-left: 12px;
 | 
			
		||||
	font-size: 14px;
 | 
			
		||||
	color: #606266;
 | 
			
		||||
	font-weight: 700;
 | 
			
		||||
	margin-bottom: 12px;
 | 
			
		||||
 | 
			
		||||
	&::before {
 | 
			
		||||
		content: '';
 | 
			
		||||
		position: absolute;
 | 
			
		||||
		left: 0;
 | 
			
		||||
		top: 6px;
 | 
			
		||||
		height: 16px;
 | 
			
		||||
		width: 4px;
 | 
			
		||||
		border-radius: 1px;
 | 
			
		||||
		background: #0b58ff;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.echarts__status-chart {
 | 
			
		||||
	background: #ccc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.echarts__status-chart > div {
 | 
			
		||||
	height: 100% !important;
 | 
			
		||||
	width: 100% !important;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -64,8 +64,7 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
// import * as echarts from 'echarts';
 | 
			
		||||
import Gantt from './demo';
 | 
			
		||||
import Gantt from './chart';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	name: 'SGStatus',
 | 
			
		||||
@@ -445,7 +444,7 @@ export default {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.running {
 | 
			
		||||
	background-color: #5ad8a6;
 | 
			
		||||
	background-color: #288AFF;
 | 
			
		||||
	// background-color: #84f04e;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -456,7 +455,7 @@ export default {
 | 
			
		||||
 | 
			
		||||
.fault {
 | 
			
		||||
	// background-color: #ea5b5b;
 | 
			
		||||
	background-color: #fc9c91;
 | 
			
		||||
	background-color: #FC9C91;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.full {
 | 
			
		||||
@@ -470,7 +469,7 @@ export default {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.stop {
 | 
			
		||||
	background-color: #000;
 | 
			
		||||
	background-color: #FFDC94;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.legend-row {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user