Compare commits
31 Commits
bb44001961
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d77506ed31 | ||
|
|
f03cf59e73 | ||
|
|
c2e901e4bc | ||
|
|
8cf50b9cb9 | ||
| 04e98ab1db | |||
| 347e51e9a4 | |||
|
|
fe7b34615a | ||
| 1b0746cc2d | |||
|
|
c992fa0200 | ||
| b97532e4e1 | |||
|
|
82573307e9 | ||
| 20f5cec3e9 | |||
|
|
67d59c5693 | ||
| 43f7ccac4c | |||
|
|
55947ceb16 | ||
|
|
fccd2ab9cc | ||
| e44b2b5f5b | |||
|
|
43a6f59afe | ||
| aeb43c8d41 | |||
| 5652cff730 | |||
|
|
f66b3a8a7a | ||
|
|
476b936660 | ||
|
|
59c652c3cf | ||
|
|
bb7f77e3ac | ||
| e306b0f837 | |||
|
|
85cc0c4c43 | ||
|
|
cfcdf4eb0a | ||
| ae7adebae0 | |||
| ae3c430d38 | |||
| d4001ed86e | |||
| 9cdd255947 |
@@ -134,6 +134,12 @@ function handleResolutionChange(width, height) {
|
|||||||
</div>
|
</div>
|
||||||
<!-- <button @click="handleIgnore" class="alert-btn">忽略</button> -->
|
<!-- <button @click="handleIgnore" class="alert-btn">忽略</button> -->
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
|
<ul class="main-screen-navigator alert-screen-navigator">
|
||||||
|
<li><a href="/main-screen">主屏页面</a></li>
|
||||||
|
<li class="active">报警列表</li>
|
||||||
|
<li><a href="/1-1">分屏页面</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
105
src/MainPage.vue
105
src/MainPage.vue
@@ -13,7 +13,7 @@ import { useSettings } from "./store/settings";
|
|||||||
|
|
||||||
const props = defineProps(["path"]);
|
const props = defineProps(["path"]);
|
||||||
|
|
||||||
const pages = ['3d', 'data', 'realtime', 'alert', 'announcement']
|
const pages = ["3d", "data", "realtime", "alert", "announcement"];
|
||||||
const currentPage = ref("3d");
|
const currentPage = ref("3d");
|
||||||
const handlePageChange = (page) => {
|
const handlePageChange = (page) => {
|
||||||
currentPage.value = page;
|
currentPage.value = page;
|
||||||
@@ -23,67 +23,84 @@ const mainContainer = ref(null);
|
|||||||
const store = useSettings();
|
const store = useSettings();
|
||||||
const timer = ref(null);
|
const timer = ref(null);
|
||||||
|
|
||||||
store.$subscribe((mutation, state) => {
|
function startCarousel(pages, duration) {
|
||||||
// 如果更新了时间
|
|
||||||
if (mutation.events.key == 'carouselTime' && state.settings.carouselTime > 0 && state.settings.carousel) {
|
|
||||||
if (timer.value) clearInterval(timer.value);
|
if (timer.value) clearInterval(timer.value);
|
||||||
timer.value = setInterval(() => {
|
timer.value = setInterval(() => {
|
||||||
handlePageChange(pages[(pages.indexOf(currentPage.value) + 1) % pages.length])
|
handlePageChange(
|
||||||
}, state.settings.carouselTime * 1000);
|
pages[(pages.indexOf(currentPage.value) + 1) % pages.length]
|
||||||
} else if (mutation.events.key == 'carousel') {
|
);
|
||||||
|
}, duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
store.$subscribe((mutation, state) => {
|
||||||
|
const pages = state.settings.carouselPages;
|
||||||
|
// 如果更新了时间
|
||||||
|
if (
|
||||||
|
mutation.events.key == "carouselTime" &&
|
||||||
|
state.settings.carouselTime > 0 &&
|
||||||
|
state.settings.carousel
|
||||||
|
) {
|
||||||
|
startCarousel(pages, state.settings.carouselTime * 1000);
|
||||||
|
} else if (mutation.events.key == "carousel") {
|
||||||
// 如果更新了状态
|
// 如果更新了状态
|
||||||
if (state.settings.carousel) {
|
if (state.settings.carousel) {
|
||||||
timer.value = setInterval(() => {
|
startCarousel(pages, state.settings.carouselTime * 1000);
|
||||||
handlePageChange(pages[(pages.indexOf(currentPage.value) + 1) % pages.length])
|
} else {
|
||||||
}, state.settings.carouselTime * 1000);
|
clearInterval(timer.value);
|
||||||
|
timer.value = null;
|
||||||
|
}
|
||||||
|
} else if (mutation.events.key == "carouselPages") {
|
||||||
|
if (state.settings.carousel) {
|
||||||
|
startCarousel(pages, state.settings.carouselTime * 1000);
|
||||||
} else {
|
} else {
|
||||||
clearInterval(timer.value);
|
clearInterval(timer.value);
|
||||||
timer.value = null;
|
timer.value = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
// 检查状态
|
// 检查状态
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const settings = store.settings;
|
const settings = store.settings;
|
||||||
|
const pages = settings.carouselPages;
|
||||||
if (settings.carousel) {
|
if (settings.carousel) {
|
||||||
// 开始轮播
|
// 开始轮播
|
||||||
if (timer.value) clearInterval(timer.value);
|
if (timer.value) clearInterval(timer.value);
|
||||||
timer.value = setInterval(() => {
|
timer.value = setInterval(() => {
|
||||||
handlePageChange(pages[(pages.indexOf(currentPage.value) + 1) % pages.length])
|
handlePageChange(
|
||||||
|
pages[(pages.indexOf(currentPage.value) + 1) % pages.length]
|
||||||
|
);
|
||||||
}, settings.carouselTime * 1000);
|
}, settings.carouselTime * 1000);
|
||||||
}
|
}
|
||||||
// 设置分辨率
|
// 设置分辨率
|
||||||
handleResolutionChange(settings.resolution.width, settings.resolution.height);
|
handleResolutionChange(settings.resolution.width, settings.resolution.height);
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
const pathMap = {
|
const pathMap = {
|
||||||
// 钢三线
|
// 钢三线
|
||||||
'/3-1': 1,
|
"/3-1": 1,
|
||||||
'/3-2': 2,
|
"/3-2": 2,
|
||||||
'/3-3': 11, // 3,
|
"/3-3": 11, // 3,
|
||||||
'/3-4': 12,
|
"/3-4": 12,
|
||||||
// 钢二线
|
// 钢二线
|
||||||
'/2-1': 5,
|
"/2-1": 5,
|
||||||
'/2-2': 6,
|
"/2-2": 6,
|
||||||
'/2-3': 7,
|
"/2-3": 7,
|
||||||
'/2-4': 4,
|
"/2-4": 4,
|
||||||
// 钢一线
|
// 钢一线
|
||||||
'/1-1': 9,
|
"/1-1": 9,
|
||||||
'/1-2': 10,
|
"/1-2": 10,
|
||||||
'/1-3': 3,
|
"/1-3": 3,
|
||||||
'/1-4': 8
|
"/1-4": 8,
|
||||||
}
|
};
|
||||||
|
|
||||||
function handleResolutionChange(width, height) {
|
function handleResolutionChange(width, height) {
|
||||||
console.log('document.documentElement', document.documentElement)
|
console.log("document.documentElement", document.documentElement);
|
||||||
if (mainContainer.value) {
|
if (mainContainer.value) {
|
||||||
// mainContainer.value.style.width = `${width}px`;
|
// mainContainer.value.style.width = `${width}px`;
|
||||||
// mainContainer.value.style.height = `${height}px`;
|
// mainContainer.value.style.height = `${height}px`;
|
||||||
// changeScale(mainContainer.value, width, height)
|
// changeScale(mainContainer.value, width, height)
|
||||||
changeScale(mainContainer.value, width, height)
|
changeScale(mainContainer.value, width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,23 +119,37 @@ function resetScale(elm) {
|
|||||||
elm.style.transform = "initial";
|
elm.style.transform = "initial";
|
||||||
elm.style.transformOrigin = "initial";
|
elm.style.transformOrigin = "initial";
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div id="main-container" ref="mainContainer" class="main-container">
|
<div id="main-container" ref="mainContainer" class="main-container">
|
||||||
<DatetimeTool v-if="currentPage !== 'announcement'" />
|
<DatetimeTool v-if="currentPage !== 'announcement'" />
|
||||||
<Tools v-if="currentPage !== 'announcement'" @change-resolution="handleResolutionChange" />
|
<Tools
|
||||||
|
v-if="currentPage !== 'announcement'"
|
||||||
|
@change-resolution="handleResolutionChange"
|
||||||
|
/>
|
||||||
<AppHeader v-if="currentPage !== 'announcement'" />
|
<AppHeader v-if="currentPage !== 'announcement'" />
|
||||||
<AnnoucementPage v-if="currentPage === 'announcement'" class="annoucement-page"
|
<AnnoucementPage
|
||||||
@home="() => handlePageChange('3d')" />
|
v-if="currentPage === 'announcement'"
|
||||||
|
class="annoucement-page"
|
||||||
|
@home="() => handlePageChange('3d')"
|
||||||
|
/>
|
||||||
<div v-else class="pages-wrapper">
|
<div v-else class="pages-wrapper">
|
||||||
<NavMenu @change="handlePageChange" :value="currentPage" />
|
<NavMenu @change="handlePageChange" :value="currentPage" />
|
||||||
<!-- <TriplePage v-if="currentPage === '3d'" :line="pathMap[path] ?? '1'" /> -->
|
<!-- <TriplePage v-if="currentPage === '3d'" :line="pathMap[path] ?? '1'" /> -->
|
||||||
<ThreeDimension v-if="currentPage === '3d'" :line="pathMap[path] ?? '1'" />
|
<ThreeDimension
|
||||||
|
v-if="currentPage === '3d'"
|
||||||
|
:line="pathMap[path] ?? '1'"
|
||||||
|
/>
|
||||||
<DataPage v-if="currentPage === 'data'" :line="pathMap[path] ?? '1'" />
|
<DataPage v-if="currentPage === 'data'" :line="pathMap[path] ?? '1'" />
|
||||||
<AlertListPage v-if="currentPage === 'alert'" :line="pathMap[path] ?? '1'" />
|
<AlertListPage
|
||||||
<RealtimePage v-if="currentPage === 'realtime'" :line="pathMap[path] ?? '1'" />
|
v-if="currentPage === 'alert'"
|
||||||
|
:line="pathMap[path] ?? '1'"
|
||||||
|
/>
|
||||||
|
<RealtimePage
|
||||||
|
v-if="currentPage === 'realtime'"
|
||||||
|
:line="pathMap[path] ?? '1'"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -75,10 +75,68 @@ function handleResolutionChange(width, height) {
|
|||||||
<TodayRate class=" " />
|
<TodayRate class=" " />
|
||||||
<SumRate class=" " />
|
<SumRate class=" " />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ul class="main-screen-navigator alert-screen-navigator">
|
||||||
|
<li class="active">主屏页面</li>
|
||||||
|
<li><a href="/alert-list">报警列表</a></li>
|
||||||
|
<li><a href="/1-1">分屏页面</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
ul,
|
||||||
|
li {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
.alert-screen-navigator a,
|
||||||
|
.main-screen-navigator a {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-screen-navigator,
|
||||||
|
.main-screen-navigator {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
bottom: 32px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 460px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
background: rgba(46, 175, 214, 0.1);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
user-select: none;
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-screen-navigator > li,
|
||||||
|
.main-screen-navigator > li {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease-out;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 12px 24px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-screen-navigator > li:hover,
|
||||||
|
.main-screen-navigator > li:hover {
|
||||||
|
background: rgba(5, 106, 246, 0.168);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-screen-navigator > li.active,
|
||||||
|
.main-screen-navigator > li.active {
|
||||||
|
background: rgba(5, 106, 246, 0.668);
|
||||||
|
}
|
||||||
|
|
||||||
.dark-table {
|
.dark-table {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|||||||
159
src/components/Chart/RateChart.vue
Normal file
159
src/components/Chart/RateChart.vue
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed, nextTick, onMounted, ref, watch } from "vue";
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
import getOptions from "./rateOption";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
isOnlyChild: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
rawData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
targetProduction: 0,
|
||||||
|
nowProduction: 0,
|
||||||
|
targetYield: 0,
|
||||||
|
nowYield: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
displayPlaceholder: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.isOnlyChild,
|
||||||
|
(newVal) => {
|
||||||
|
reInitChart();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const rate = computed(() => {
|
||||||
|
if (!props.rawData?.nowYield || props.rawData.nowYield == 0) return [0, 0];
|
||||||
|
// const _rate = ((props.rawData.nowYield / props.rawData.targetYield) * 100)
|
||||||
|
// .toFixed(2)
|
||||||
|
// .toString();
|
||||||
|
// return [parseInt(_rate), _rate.split(".")[1]];
|
||||||
|
return [
|
||||||
|
parseInt(props.rawData.nowYield),
|
||||||
|
((props.rawData.nowYield + "").split(".")[1] ?? "").padStart(2, "0"),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
const chart = ref(null);
|
||||||
|
const rateChartRef = ref(null);
|
||||||
|
|
||||||
|
function reInitChart() {
|
||||||
|
if (chart.value) chart.value.dispose();
|
||||||
|
const _chart = echarts.init(rateChartRef.value);
|
||||||
|
_chart.setOption(getOptions(props.rawData));
|
||||||
|
chart.value = _chart;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
reInitChart();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="chart rate-chart">
|
||||||
|
<div ref="rateChartRef" class="chart-container"></div>
|
||||||
|
|
||||||
|
<div :class="['fake-chart-title', isOnlyChild ? 'is-only-child' : '']">
|
||||||
|
<span class="integer-part">{{ rate[0] }}.</span>
|
||||||
|
<span class="decimal-part">{{ rate[1] }}%</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-intro">
|
||||||
|
<div class="text-intro__item">
|
||||||
|
<span class="legend-box green"></span>
|
||||||
|
<span>当前成品率: {{ props.rawData?.nowYield ?? 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-intro__item">
|
||||||
|
<span class="legend-box blue"></span>
|
||||||
|
<span>目标成品率: {{ props.rawData?.targetYield ?? 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.rate-chart {
|
||||||
|
height: 240px;
|
||||||
|
flex-grow: 1;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-placeholder,
|
||||||
|
.chart-container {
|
||||||
|
margin: auto;
|
||||||
|
width: 320px;
|
||||||
|
height: 100%;
|
||||||
|
background: "#0f01";
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fake-chart-title {
|
||||||
|
user-select: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 30%;
|
||||||
|
left: 36%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fake-chart-title.is-only-child {
|
||||||
|
left: 36%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fake-chart-title > .integer-part {
|
||||||
|
font-size: 48px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fake-chart-title > .decimal-part {
|
||||||
|
font-size: 32px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-intro {
|
||||||
|
position: absolute;
|
||||||
|
height: auto;
|
||||||
|
width: 240px;
|
||||||
|
bottom: 18px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 12px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-intro__item {
|
||||||
|
font-size: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-box {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.green {
|
||||||
|
background: #4cf0e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blue {
|
||||||
|
background: #1065ff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
110
src/components/Chart/YieldChart.vue
Normal file
110
src/components/Chart/YieldChart.vue
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<script setup>
|
||||||
|
import { nextTick, onMounted, ref, watch } from "vue";
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
import getOptions from "./yieldOption";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
rawData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
targetProduction: 0,
|
||||||
|
nowProduction: 0,
|
||||||
|
targetYield: 0,
|
||||||
|
nowYield: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
displayPlaceholder: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const chart = ref(null);
|
||||||
|
const yieldChartRef = ref(null);
|
||||||
|
|
||||||
|
function reInitChart() {
|
||||||
|
// if (props.displayPlaceholder) return;
|
||||||
|
if (chart.value) chart.value.dispose();
|
||||||
|
const _chart = echarts.init(yieldChartRef.value);
|
||||||
|
_chart.setOption(
|
||||||
|
getOptions(
|
||||||
|
props.rawData ?? {
|
||||||
|
nowProduction: 0,
|
||||||
|
targetProduction: 0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
chart.value = _chart;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
reInitChart();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="chart yield-chart">
|
||||||
|
<!-- <div v-if="displayPlaceholder" class="chart-placeholder"></div>
|
||||||
|
<div v-else ref="yieldChartRef" class="chart-container"></div> -->
|
||||||
|
<div ref="yieldChartRef" class="chart-container"></div>
|
||||||
|
<div class="text-intro">
|
||||||
|
<div class="text-intro__item">
|
||||||
|
<span class="legend-box green"></span>
|
||||||
|
<span>当前产量: {{ rawData?.nowProduction ?? 0 }}片</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="!displayPlaceholder" class="text-intro__item">
|
||||||
|
<span>目标产量: {{ rawData?.targetProduction ?? 0 }}片</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.yield-chart {
|
||||||
|
height: 240px;
|
||||||
|
flex-grow: 1;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-placeholder,
|
||||||
|
.chart-container {
|
||||||
|
margin: auto;
|
||||||
|
width: 320px;
|
||||||
|
height: 100%;
|
||||||
|
background: "#0f01";
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-intro {
|
||||||
|
position: absolute;
|
||||||
|
height: auto;
|
||||||
|
width: 220px;
|
||||||
|
bottom: 18px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 12px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-intro__item {
|
||||||
|
font-size: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-box {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #4cf0e8;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
149
src/components/Chart/rateOption.js
Normal file
149
src/components/Chart/rateOption.js
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
const radius = ["58%", "72%"];
|
||||||
|
const radius2 = ["45%", "58%"];
|
||||||
|
const grid = {
|
||||||
|
top: 0,
|
||||||
|
left: 24,
|
||||||
|
right: 24,
|
||||||
|
bottom: 32,
|
||||||
|
};
|
||||||
|
const title = {
|
||||||
|
// 由外部负责展示,此处占位
|
||||||
|
text: " ",
|
||||||
|
left: "50%",
|
||||||
|
top: "30%",
|
||||||
|
textAlign: "center",
|
||||||
|
textStyle: {
|
||||||
|
fontWeight: 400,
|
||||||
|
fontSize: 48,
|
||||||
|
color: "#fffd",
|
||||||
|
},
|
||||||
|
subtext: "当前成品率\u2002",
|
||||||
|
subtextStyle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: 100,
|
||||||
|
color: "#fffd",
|
||||||
|
align: "right",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const tooltip = {
|
||||||
|
// trigger: "item",
|
||||||
|
show: false,
|
||||||
|
};
|
||||||
|
const legend = {
|
||||||
|
top: "5%",
|
||||||
|
left: "center",
|
||||||
|
};
|
||||||
|
const bgSerie = {
|
||||||
|
type: "pie",
|
||||||
|
radius: radius,
|
||||||
|
center: ["50%", "40%"],
|
||||||
|
emptyCircleStyle: {
|
||||||
|
color: "#042c5f33",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const dataSerie = {
|
||||||
|
type: "pie",
|
||||||
|
radius: radius,
|
||||||
|
center: ["50%", "40%"],
|
||||||
|
avoidLabelOvervlap: false,
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
// position: "center",
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
value: 90,
|
||||||
|
name: "当前成品率",
|
||||||
|
selected: false,
|
||||||
|
itemStyle: {
|
||||||
|
borderJoin: "round",
|
||||||
|
borderCap: "round",
|
||||||
|
borderWidth: 12,
|
||||||
|
borderRadius: "50%",
|
||||||
|
color: {
|
||||||
|
type: "linear",
|
||||||
|
x: 1,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: "#4CF0E811" },
|
||||||
|
{ offset: 1, color: "#4CF0E8" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 20,
|
||||||
|
name: "-",
|
||||||
|
itemStyle: { color: "transparent" },
|
||||||
|
label: { show: false },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const targetSerie = {
|
||||||
|
type: "pie",
|
||||||
|
radius: radius2,
|
||||||
|
center: ["50%", "40%"],
|
||||||
|
avoidLabelOvervlap: false,
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
value: 90,
|
||||||
|
name: "目标成品率",
|
||||||
|
selected: false,
|
||||||
|
itemStyle: {
|
||||||
|
borderJoin: "round",
|
||||||
|
borderCap: "round",
|
||||||
|
borderWidth: 12,
|
||||||
|
borderRadius: "50%",
|
||||||
|
color: {
|
||||||
|
type: "linear",
|
||||||
|
x: 1,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: "#1065ff66" },
|
||||||
|
{ offset: 1, color: "#1065ff" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 20,
|
||||||
|
name: "-",
|
||||||
|
itemStyle: { color: "transparent" },
|
||||||
|
label: { show: false },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default (data) => {
|
||||||
|
title.subtext = "当前成品率\u2002";
|
||||||
|
dataSerie.data[0].value = data?.nowYield ?? 0;
|
||||||
|
dataSerie.data[1].value = 100 - (data?.nowYield ?? 0);
|
||||||
|
targetSerie.data[0].value = data?.targetYield ?? 0;
|
||||||
|
targetSerie.data[1].value = 100 - (data?.targetYield ?? 0);
|
||||||
|
return {
|
||||||
|
tooltip,
|
||||||
|
title,
|
||||||
|
grid,
|
||||||
|
series: [
|
||||||
|
// background
|
||||||
|
bgSerie,
|
||||||
|
// actual data
|
||||||
|
dataSerie,
|
||||||
|
// target data
|
||||||
|
targetSerie,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
};
|
||||||
157
src/components/Chart/yieldOption.js
Normal file
157
src/components/Chart/yieldOption.js
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
const radius = ["58%", "72%"];
|
||||||
|
const radius2 = ["45%", "58%"];
|
||||||
|
const grid = {
|
||||||
|
top: 0,
|
||||||
|
left: 24,
|
||||||
|
right: 24,
|
||||||
|
bottom: 32,
|
||||||
|
};
|
||||||
|
const title = {
|
||||||
|
text: "75%",
|
||||||
|
left: "50%",
|
||||||
|
top: "30%",
|
||||||
|
textAlign: "center",
|
||||||
|
textStyle: {
|
||||||
|
fontWeight: 400,
|
||||||
|
fontSize: 48,
|
||||||
|
color: "#fffd",
|
||||||
|
},
|
||||||
|
subtext: "当前产量\u2002",
|
||||||
|
subtextStyle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: 100,
|
||||||
|
color: "#fffd",
|
||||||
|
align: "right",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const tooltip = {
|
||||||
|
// trigger: "item",
|
||||||
|
show: false,
|
||||||
|
};
|
||||||
|
const legend = {
|
||||||
|
top: "5%",
|
||||||
|
left: "center",
|
||||||
|
};
|
||||||
|
const bgSerie = {
|
||||||
|
type: "pie",
|
||||||
|
radius: radius,
|
||||||
|
center: ["50%", "40%"],
|
||||||
|
emptyCircleStyle: {
|
||||||
|
color: "#042c5f33",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const dataSerie = {
|
||||||
|
type: "pie",
|
||||||
|
radius: radius,
|
||||||
|
center: ["50%", "40%"],
|
||||||
|
avoidLabelOvervlap: false,
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
// position: "center",
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
value: 90,
|
||||||
|
name: "当前产量",
|
||||||
|
selected: false,
|
||||||
|
itemStyle: {
|
||||||
|
borderJoin: "round",
|
||||||
|
borderCap: "round",
|
||||||
|
borderWidth: 12,
|
||||||
|
borderRadius: "50%",
|
||||||
|
color: {
|
||||||
|
type: "linear",
|
||||||
|
x: 1,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: "#4CF0E811" },
|
||||||
|
{ offset: 1, color: "#4CF0E8" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 20,
|
||||||
|
name: "-",
|
||||||
|
itemStyle: { color: "transparent" },
|
||||||
|
label: { show: false },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const targetSerie = {
|
||||||
|
type: "pie",
|
||||||
|
radius: radius2,
|
||||||
|
center: ["50%", "40%"],
|
||||||
|
avoidLabelOvervlap: false,
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
value: 90,
|
||||||
|
name: "目标成产量",
|
||||||
|
selected: false,
|
||||||
|
itemStyle: {
|
||||||
|
borderJoin: "round",
|
||||||
|
borderCap: "round",
|
||||||
|
borderWidth: 12,
|
||||||
|
borderRadius: "50%",
|
||||||
|
color: {
|
||||||
|
type: "linear",
|
||||||
|
x: 1,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: "#1065ff66" },
|
||||||
|
{ offset: 1, color: "#1065ff" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 20,
|
||||||
|
name: "-",
|
||||||
|
itemStyle: { color: "transparent" },
|
||||||
|
label: { show: false },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default (data) => {
|
||||||
|
// title.text =
|
||||||
|
// (100 * (+data.nowProduction / +data.targetProduction)).toFixed(0) + "%";
|
||||||
|
// 外圈
|
||||||
|
title.text = data.nowProduction || 0;
|
||||||
|
dataSerie.data[0].value = data.nowProduction;
|
||||||
|
dataSerie.data[1].value = !data.targetProduction
|
||||||
|
? data.nowProduction == 0
|
||||||
|
? 1
|
||||||
|
: 0
|
||||||
|
: data.targetProduction - data.nowProduction;
|
||||||
|
|
||||||
|
// 内圈
|
||||||
|
targetSerie.data[0].value = data?.targetProduction ?? 0;
|
||||||
|
targetSerie.data[1].value = data?.targetProduction ? 0 : 1;
|
||||||
|
|
||||||
|
return {
|
||||||
|
tooltip,
|
||||||
|
title,
|
||||||
|
grid,
|
||||||
|
series: [
|
||||||
|
// background
|
||||||
|
bgSerie,
|
||||||
|
dataSerie,
|
||||||
|
targetSerie,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -25,15 +25,9 @@ store.$subscribe((mutation, state) => {
|
|||||||
if (chart.value) chart.value.dispose();
|
if (chart.value) chart.value.dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hourData.value = (state.data2?.lineHourList ?? [
|
hourData.value = (state.data2?.lineHourList ?? []).map((item, index) => ({
|
||||||
// { lineName: '001', hour: '00:00', num: 10 },
|
|
||||||
// { lineName: '002', hour: '00:20', num: 20 },
|
|
||||||
// { lineName: '003', hour: '00:30', num: 30 },
|
|
||||||
// { lineName: '004', hour: '00:40', num: 14 },
|
|
||||||
// { lineName: '005', hour: '00:50', num: 50 },
|
|
||||||
]).map((item, index) => ({
|
|
||||||
id: `${item.lineName}_${index}`,
|
id: `${item.lineName}_${index}`,
|
||||||
hour: item.hour || '__',
|
hour: item.hour || "__",
|
||||||
data: item.num || 0,
|
data: item.num || 0,
|
||||||
}));
|
}));
|
||||||
setupChart();
|
setupChart();
|
||||||
@@ -46,7 +40,7 @@ function setupChart() {
|
|||||||
chartSetup(
|
chartSetup(
|
||||||
chart.value,
|
chart.value,
|
||||||
hourData.value.map((item) => item.hour),
|
hourData.value.map((item) => item.hour),
|
||||||
hourData.value.map((item) => item.num)
|
hourData.value.map((item) => item.data)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -12,45 +12,45 @@ const show = ref(false);
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
chartContainer.value.classList.add("h-full");
|
chartContainer.value.classList.add("h-full");
|
||||||
// const d = loadData(store.data2.lineSevenDayLogList);
|
const d = loadData(store.data2.lineSevenDayLogList);
|
||||||
const d = loadData([
|
// const d = loadData([
|
||||||
{
|
// {
|
||||||
data: [
|
// data: [
|
||||||
{ day: "10-10", num: Math.floor(Math.random() * 500) },
|
// { day: "10-10", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-11", num: Math.floor(Math.random() * 500) },
|
// { day: "10-11", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-12", num: Math.floor(Math.random() * 500) },
|
// { day: "10-12", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-13", num: Math.floor(Math.random() * 500) },
|
// { day: "10-13", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-14", num: Math.floor(Math.random() * 500) },
|
// { day: "10-14", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-15", num: Math.floor(Math.random() * 500) },
|
// { day: "10-15", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-16", num: Math.floor(Math.random() * 500) },
|
// { day: "10-16", num: Math.floor(Math.random() * 500) },
|
||||||
],
|
// ],
|
||||||
name: "钢一线",
|
// name: "钢一线",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
data: [
|
// data: [
|
||||||
{ day: "10-10", num: Math.floor(Math.random() * 500) },
|
// { day: "10-10", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-11", num: Math.floor(Math.random() * 500) },
|
// { day: "10-11", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-12", num: Math.floor(Math.random() * 500) },
|
// { day: "10-12", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-13", num: Math.floor(Math.random() * 500) },
|
// { day: "10-13", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-14", num: Math.floor(Math.random() * 500) },
|
// { day: "10-14", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-15", num: Math.floor(Math.random() * 500) },
|
// { day: "10-15", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-16", num: Math.floor(Math.random() * 500) },
|
// { day: "10-16", num: Math.floor(Math.random() * 500) },
|
||||||
],
|
// ],
|
||||||
name: "钢二线",
|
// name: "钢二线",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
data: [
|
// data: [
|
||||||
{ day: "10-10", num: Math.floor(Math.random() * 500) },
|
// { day: "10-10", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-11", num: Math.floor(Math.random() * 500) },
|
// { day: "10-11", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-12", num: Math.floor(Math.random() * 500) },
|
// { day: "10-12", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-13", num: Math.floor(Math.random() * 500) },
|
// { day: "10-13", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-14", num: Math.floor(Math.random() * 500) },
|
// { day: "10-14", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-15", num: Math.floor(Math.random() * 500) },
|
// { day: "10-15", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-16", num: Math.floor(Math.random() * 500) },
|
// { day: "10-16", num: Math.floor(Math.random() * 500) },
|
||||||
],
|
// ],
|
||||||
name: "钢三线",
|
// name: "钢三线",
|
||||||
},
|
// },
|
||||||
]);
|
// ]);
|
||||||
if (!d) {
|
if (!d) {
|
||||||
show.value = false;
|
show.value = false;
|
||||||
if (chartInstance.value) {
|
if (chartInstance.value) {
|
||||||
@@ -67,45 +67,45 @@ onMounted(() => {
|
|||||||
|
|
||||||
// 订阅
|
// 订阅
|
||||||
store.$subscribe((mutation, state) => {
|
store.$subscribe((mutation, state) => {
|
||||||
// const d = loadData(state.data2.lineSevenDayLogList);
|
const d = loadData(state.data2.lineSevenDayLogList);
|
||||||
const d = loadData([
|
// const d = loadData([
|
||||||
{
|
// {
|
||||||
data: [
|
// data: [
|
||||||
{ day: "10-10", num: Math.floor(Math.random() * 500) },
|
// { day: "10-10", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-11", num: Math.floor(Math.random() * 500) },
|
// { day: "10-11", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-12", num: Math.floor(Math.random() * 500) },
|
// { day: "10-12", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-13", num: Math.floor(Math.random() * 500) },
|
// { day: "10-13", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-14", num: Math.floor(Math.random() * 500) },
|
// { day: "10-14", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-15", num: Math.floor(Math.random() * 500) },
|
// { day: "10-15", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-16", num: Math.floor(Math.random() * 500) },
|
// { day: "10-16", num: Math.floor(Math.random() * 500) },
|
||||||
],
|
// ],
|
||||||
name: "钢一线",
|
// name: "钢一线",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
data: [
|
// data: [
|
||||||
{ day: "10-10", num: Math.floor(Math.random() * 500) },
|
// { day: "10-10", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-11", num: Math.floor(Math.random() * 500) },
|
// { day: "10-11", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-12", num: Math.floor(Math.random() * 500) },
|
// { day: "10-12", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-13", num: Math.floor(Math.random() * 500) },
|
// { day: "10-13", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-14", num: Math.floor(Math.random() * 500) },
|
// { day: "10-14", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-15", num: Math.floor(Math.random() * 500) },
|
// { day: "10-15", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-16", num: Math.floor(Math.random() * 500) },
|
// { day: "10-16", num: Math.floor(Math.random() * 500) },
|
||||||
],
|
// ],
|
||||||
name: "钢二线",
|
// name: "钢二线",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
data: [
|
// data: [
|
||||||
{ day: "10-10", num: Math.floor(Math.random() * 500) },
|
// { day: "10-10", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-11", num: Math.floor(Math.random() * 500) },
|
// { day: "10-11", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-12", num: Math.floor(Math.random() * 500) },
|
// { day: "10-12", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-13", num: Math.floor(Math.random() * 500) },
|
// { day: "10-13", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-14", num: Math.floor(Math.random() * 500) },
|
// { day: "10-14", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-15", num: Math.floor(Math.random() * 500) },
|
// { day: "10-15", num: Math.floor(Math.random() * 500) },
|
||||||
{ day: "10-16", num: Math.floor(Math.random() * 500) },
|
// { day: "10-16", num: Math.floor(Math.random() * 500) },
|
||||||
],
|
// ],
|
||||||
name: "钢三线",
|
// name: "钢三线",
|
||||||
},
|
// },
|
||||||
]);
|
// ]);
|
||||||
if (!d) {
|
if (!d) {
|
||||||
show.value = false;
|
show.value = false;
|
||||||
if (chartInstance.value) {
|
if (chartInstance.value) {
|
||||||
|
|||||||
@@ -1,27 +1,33 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from "vue";
|
||||||
import { useSettings } from '../store/settings'
|
import { useSettings } from "../store/settings";
|
||||||
const emit = defineEmits(["close", "change-resolution"]);
|
const emit = defineEmits(["close", "change-resolution"]);
|
||||||
|
|
||||||
const store = useSettings();
|
const store = useSettings();
|
||||||
const settings = ref(store.settings);
|
const settings = ref(store.settings);
|
||||||
store.$subscribe((mutation, state) => {
|
store.$subscribe((mutation, state) => {
|
||||||
settings.value.fullscreen = state.settings.fullscreen;
|
settings.value.fullscreen = state.settings.fullscreen;
|
||||||
})
|
});
|
||||||
|
|
||||||
function handleCancel() {
|
function handleCancel() {
|
||||||
emit('close')
|
emit("close");
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleConfirm() {
|
function handleConfirm() {
|
||||||
// alert(JSON.stringify(settings, null, 2))
|
if (settings.value.resolution.width < 480)
|
||||||
// changeScale(settings.resolution.width, settings.resolution.height)
|
store.settings.resolution.width = 480;
|
||||||
if (settings.value.resolution.width < 480) store.settings.resolution.width = 480;
|
if (settings.value.resolution.width > 7680)
|
||||||
if (settings.value.resolution.width > 7680) store.settings.resolution.width = 7680;
|
store.settings.resolution.width = 7680;
|
||||||
if (settings.value.resolution.height < 270) store.settings.resolution.height = 270;
|
if (settings.value.resolution.height < 270)
|
||||||
if (settings.value.resolution.height > 4320) store.settings.resolution.height = 4320;
|
store.settings.resolution.height = 270;
|
||||||
|
if (settings.value.resolution.height > 4320)
|
||||||
|
store.settings.resolution.height = 4320;
|
||||||
|
|
||||||
emit('change-resolution', store.settings.resolution.width, store.settings.resolution.height)
|
emit(
|
||||||
|
"change-resolution",
|
||||||
|
store.settings.resolution.width,
|
||||||
|
store.settings.resolution.height
|
||||||
|
);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -34,22 +40,146 @@ function handleConfirm() {
|
|||||||
<input id="carousel" type="number" v-model="settings.carouselTime" />
|
<input id="carousel" type="number" v-model="settings.carouselTime" />
|
||||||
<span>秒</span>
|
<span>秒</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="form-item"
|
||||||
|
style="display: flex; flex-direction: column; gap: 12px"
|
||||||
|
>
|
||||||
|
<label for="carouselPages">轮播项目</label>
|
||||||
|
<div class="carousel-page__list">
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="cp-3d"
|
||||||
|
name="carouselPages"
|
||||||
|
:class="[
|
||||||
|
settings.carouselPages.includes('3d') ? 'checked' : '',
|
||||||
|
'carousel-page',
|
||||||
|
]"
|
||||||
|
@change="
|
||||||
|
() => {
|
||||||
|
store.updateSettings({ type: 'carousel-page', value: '3d' });
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<label for="cp-3d">三维界面</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="cp-data"
|
||||||
|
name="carouselPages"
|
||||||
|
:class="[
|
||||||
|
settings.carouselPages.includes('data') ? 'checked' : '',
|
||||||
|
'carousel-page',
|
||||||
|
]"
|
||||||
|
@change="
|
||||||
|
() => {
|
||||||
|
store.updateSettings({
|
||||||
|
type: 'carousel-page',
|
||||||
|
value: 'data',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<label for="cp-data">数据界面</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="cp-realtime"
|
||||||
|
name="carouselPages"
|
||||||
|
:class="[
|
||||||
|
settings.carouselPages.includes('realtime') ? 'checked' : '',
|
||||||
|
'carousel-page',
|
||||||
|
]"
|
||||||
|
@change="
|
||||||
|
() => {
|
||||||
|
store.updateSettings({
|
||||||
|
type: 'carousel-page',
|
||||||
|
value: 'realtime',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<label for="cp-realtime">实时数据</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="cp-alert"
|
||||||
|
name="carouselPages"
|
||||||
|
:class="[
|
||||||
|
settings.carouselPages.includes('alert') ? 'checked' : '',
|
||||||
|
'carousel-page',
|
||||||
|
]"
|
||||||
|
@change="
|
||||||
|
() => {
|
||||||
|
store.updateSettings({
|
||||||
|
type: 'carousel-page',
|
||||||
|
value: 'alert',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<label for="cp-alert">报警列表</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="cp-announcement"
|
||||||
|
name="carouselPages"
|
||||||
|
:class="[
|
||||||
|
settings.carouselPages.includes('announcement')
|
||||||
|
? 'checked'
|
||||||
|
: '',
|
||||||
|
'carousel-page',
|
||||||
|
]"
|
||||||
|
@change="
|
||||||
|
() => {
|
||||||
|
store.updateSettings({
|
||||||
|
type: 'carousel-page',
|
||||||
|
value: 'announcement',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<label for="cp-announcement">公告页面</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-item">
|
<div class="form-item">
|
||||||
<label for="resolution1">分辨率</label>
|
<label for="resolution1">分辨率</label>
|
||||||
<input id="resolution1" type="number" min="480" max="7680" v-model="settings.resolution.width" />
|
<input
|
||||||
|
id="resolution1"
|
||||||
|
type="number"
|
||||||
|
min="480"
|
||||||
|
max="7680"
|
||||||
|
v-model="settings.resolution.width"
|
||||||
|
/>
|
||||||
<span>X</span>
|
<span>X</span>
|
||||||
<input id="resolution2" type="number" min="270" max="4320" v-model="settings.resolution.height" />
|
<input
|
||||||
|
id="resolution2"
|
||||||
|
type="number"
|
||||||
|
min="270"
|
||||||
|
max="4320"
|
||||||
|
v-model="settings.resolution.height"
|
||||||
|
/>
|
||||||
<span>px</span>
|
<span>px</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-item selector">
|
<div class="form-item selector">
|
||||||
<div class="opt opt1">
|
<!-- <div class="opt opt1">
|
||||||
<input type="checkbox" id="fullscreen" name="fullscreen" :class="[settings.fullscreen ? 'checked' : '']"
|
<input type="checkbox" id="fullscreen" name="fullscreen" :class="[settings.fullscreen ? 'checked' : '']"
|
||||||
v-model="settings.fullscreen" />
|
v-model="settings.fullscreen" />
|
||||||
<label for="fullscreen">全屏显示</label>
|
<label for="fullscreen">全屏显示</label>
|
||||||
</div>
|
</div> -->
|
||||||
<div class="opt opt2">
|
<div class="opt opt2">
|
||||||
<input type="checkbox" id="status" name="status" :class="[settings.eqStatus ? 'checked' : '']"
|
<input
|
||||||
v-model="settings.eqStatus" />
|
type="checkbox"
|
||||||
|
id="status"
|
||||||
|
name="status"
|
||||||
|
:class="[settings.eqStatus ? 'checked' : '', 'carousel-page']"
|
||||||
|
v-model="settings.eqStatus"
|
||||||
|
/>
|
||||||
<label for="status">设备状态</label>
|
<label for="status">设备状态</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -78,10 +208,10 @@ function handleConfirm() {
|
|||||||
height: 422px;
|
height: 422px;
|
||||||
background: url(../assets/dialog-bg.png) 100% / contain no-repeat;
|
background: url(../assets/dialog-bg.png) 100% / contain no-repeat;
|
||||||
z-index: 1001;
|
z-index: 1001;
|
||||||
transition: all .3s ease-out;
|
transition: all 0.3s ease-out;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 18px;
|
gap: 12px;
|
||||||
padding: 24px 80px;
|
padding: 24px 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,11 +221,11 @@ function handleConfirm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form-item {
|
.form-item {
|
||||||
margin: 32px 0;
|
margin: 20px 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 28px;
|
font-size: 24px;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
}
|
}
|
||||||
@@ -105,12 +235,15 @@ function handleConfirm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.opt {
|
.opt {
|
||||||
margin-left: 24px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.opt2 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.form-item input {
|
.form-item input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
border: none;
|
border: none;
|
||||||
@@ -143,7 +276,7 @@ input[type="checkbox"].checked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input[type="checkbox"].checked::after {
|
input[type="checkbox"].checked::after {
|
||||||
content: '\2713';
|
content: "\2713";
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
@@ -155,6 +288,28 @@ input[type="checkbox"].checked::after {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.carousel-page__list {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-page__list > div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"].carousel-page {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
input[type="checkbox"].carousel-page.checked::after {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
@@ -167,10 +322,10 @@ label {
|
|||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 18px;
|
padding: 12px;
|
||||||
font-size: 28px;
|
font-size: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
letter-spacing: 12px;
|
letter-spacing: 8px;
|
||||||
background: url(../assets/dialog-button.png) 0 0 / 100% 100% no-repeat;
|
background: url(../assets/dialog-button.png) 0 0 / 100% 100% no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,10 +349,10 @@ button {
|
|||||||
background: #0003;
|
background: #0003;
|
||||||
backdrop-filter: blur(3px);
|
backdrop-filter: blur(3px);
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
transition: all .3s ease-out;
|
transition: all 0.3s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-dialog>h1 {
|
.setting-dialog > h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
letter-spacing: 24px;
|
letter-spacing: 24px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|||||||
@@ -1,43 +1,47 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, nextTick } from "vue";
|
import { ref, onMounted, nextTick } from "vue";
|
||||||
import * as echarts from "echarts";
|
|
||||||
import Container from "../Base/Container.vue";
|
import Container from "../Base/Container.vue";
|
||||||
import { useWsStore } from "../../store";
|
import { useWsStore } from "../../store";
|
||||||
import setupFn from "./LineMonthOptions";
|
import YieldChart from "../Chart/YieldChart.vue";
|
||||||
|
import RateChart from "../Chart/RateChart.vue";
|
||||||
|
|
||||||
const show = ref(false);
|
const displayProductionChart = ref(false);
|
||||||
const chartContainer = ref(null);
|
const displayRateChart = ref(false);
|
||||||
const chartInstance = ref(null);
|
const websocketData = ref(null);
|
||||||
|
const refreshToken = ref(1);
|
||||||
const store = useWsStore();
|
const store = useWsStore();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
chartContainer.value.classList.add("h-full");
|
// websocketData.value = loadData([
|
||||||
const d = loadData(store.data2.monthlyTarget);
|
|
||||||
// const d = loadData([
|
|
||||||
// {
|
// {
|
||||||
// targetProduction: 100,
|
// targetProduction: 0,
|
||||||
// nowProduction: 66,
|
// nowProduction: 10,
|
||||||
// targetYield: 13,
|
// targetYield: 10.34,
|
||||||
// nowYield: 3,
|
// nowYield: 3.11,
|
||||||
// },
|
// },
|
||||||
// ]);
|
// ]);
|
||||||
if (!d) {
|
websocketData.value = loadData(store.data2.monthlyTarget);
|
||||||
show.value = false;
|
if (!websocketData.value) {
|
||||||
if (chartInstance.value) {
|
displayProductionChart.value = false;
|
||||||
chartInstance.value.dispose();
|
displayRateChart.value = false;
|
||||||
chartInstance.value = null;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!chartInstance.value)
|
/** 阻止 targetProduction == 0 */
|
||||||
chartInstance.value = echarts.init(chartContainer.value);
|
if (!websocketData.value.targetProduction) {
|
||||||
setupFn(chartInstance.value, d);
|
displayProductionChart.value = false;
|
||||||
show.value = true;
|
} else {
|
||||||
|
displayProductionChart.value = true;
|
||||||
|
}
|
||||||
|
/** 阻止 targetYield == 0 */
|
||||||
|
if (!websocketData.value.targetYield) {
|
||||||
|
displayRateChart.value = false;
|
||||||
|
} else {
|
||||||
|
displayRateChart.value = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 订阅
|
// 订阅
|
||||||
store.$subscribe((mutation, state) => {
|
store.$subscribe((mutation, state) => {
|
||||||
const d = loadData(state.data2.monthlyTarget);
|
|
||||||
// const d = loadData([
|
// const d = loadData([
|
||||||
// {
|
// {
|
||||||
// targetProduction: 100,
|
// targetProduction: 100,
|
||||||
@@ -46,30 +50,35 @@ store.$subscribe((mutation, state) => {
|
|||||||
// nowYield: 3,
|
// nowYield: 3,
|
||||||
// },
|
// },
|
||||||
// ]);
|
// ]);
|
||||||
if (!d) {
|
websocketData.value = loadData(state.data2.monthlyTarget);
|
||||||
show.value = false;
|
if (!websocketData.value) {
|
||||||
if (chartInstance.value) {
|
displayProductionChart.value = false;
|
||||||
chartInstance.value.dispose();
|
displayRateChart.value = false;
|
||||||
chartInstance.value = null;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!chartInstance.value)
|
/** 阻止 targetProduction == 0 */
|
||||||
chartInstance.value = echarts.init(chartContainer.value);
|
if (!websocketData.value.targetProduction) {
|
||||||
setupFn(chartInstance.value, d);
|
displayProductionChart.value = false;
|
||||||
show.value = true;
|
} else {
|
||||||
|
if (refreshToken.value > 100000) refreshToken.value = 0;
|
||||||
|
refreshToken.value += 1;
|
||||||
|
displayProductionChart.value = true;
|
||||||
|
}
|
||||||
|
/** 阻止 targetYield == 0 */
|
||||||
|
if (!websocketData.value.targetYield) {
|
||||||
|
displayRateChart.value = false;
|
||||||
|
} else {
|
||||||
|
if (refreshToken.value > 100000) refreshToken.value = 0;
|
||||||
|
refreshToken.value += 1;
|
||||||
|
displayRateChart.value = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// utils
|
// utils
|
||||||
function loadData(monthlyTarget) {
|
function loadData(monthlyTarget) {
|
||||||
if (
|
if (monthlyTarget == undefined || !monthlyTarget[0]) {
|
||||||
monthlyTarget == undefined ||
|
|
||||||
// monthlyTarget?.length == 0 ||
|
|
||||||
!monthlyTarget[0]
|
|
||||||
) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
targetProduction: monthlyTarget[0].targetProduction,
|
targetProduction: monthlyTarget[0].targetProduction,
|
||||||
nowProduction: monthlyTarget[0].nowProduction,
|
nowProduction: monthlyTarget[0].nowProduction,
|
||||||
@@ -81,12 +90,38 @@ function loadData(monthlyTarget) {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Container class="chart" title="本月生产线情况" icon="cube">
|
<Container class="chart" title="本月生产线情况" icon="cube">
|
||||||
<div
|
<!-- <div
|
||||||
ref="chartContainer"
|
ref="chartContainer"
|
||||||
class="chart-chart"
|
class="chart-chart"
|
||||||
:style="{ opacity: show ? 1 : 0 }"
|
:style="{ opacity: show ? 1 : 0 }"
|
||||||
></div>
|
></div>
|
||||||
<p v-show="!show" class="empty-data-hint">暂无数据</p>
|
<p v-show="!show" class="empty-data-hint">暂无数据</p> -->
|
||||||
|
<div class="container-body__h-full">
|
||||||
|
<yield-chart
|
||||||
|
:key="refreshToken + '_yield_chart_linemonth'"
|
||||||
|
:raw-data="websocketData"
|
||||||
|
/>
|
||||||
|
<rate-chart
|
||||||
|
:display-placeholder="!displayRateChart"
|
||||||
|
:key="refreshToken + '_rate_chart_linemonth'"
|
||||||
|
:raw-data="websocketData"
|
||||||
|
:isOnlyChild="!displayProductionChart"
|
||||||
|
/>
|
||||||
|
<!-- <p
|
||||||
|
v-if="!displayProductionChart && !displayRateChart"
|
||||||
|
style="
|
||||||
|
height: 100%;
|
||||||
|
line-height: 350px;
|
||||||
|
user-select: none;
|
||||||
|
flex: 1;
|
||||||
|
color: #fffc;
|
||||||
|
font-size: 24px;
|
||||||
|
text-align: center;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p> -->
|
||||||
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -99,4 +134,10 @@ function loadData(monthlyTarget) {
|
|||||||
.chart-chart {
|
.chart-chart {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container-body__h-full {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
102
src/components/datapage/LineToday copy.vue
Normal file
102
src/components/datapage/LineToday copy.vue
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, nextTick } from "vue";
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
import Container from "../Base/Container.vue";
|
||||||
|
import { useWsStore } from "../../store";
|
||||||
|
import setupFn from "./LineTodayOptions";
|
||||||
|
|
||||||
|
const show = ref(false);
|
||||||
|
const chartContainer = ref(null);
|
||||||
|
const chartInstance = ref(null);
|
||||||
|
const store = useWsStore();
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
chartContainer.value.classList.add("h-full");
|
||||||
|
const d = loadData(store.data2.dailyTarget);
|
||||||
|
// const d = loadData([
|
||||||
|
// {
|
||||||
|
// targetProduction: 100,
|
||||||
|
// nowProduction: 66,
|
||||||
|
// targetYield: 13,
|
||||||
|
// nowYield: 3,
|
||||||
|
// },
|
||||||
|
// ]);
|
||||||
|
if (!d) {
|
||||||
|
show.value = false;
|
||||||
|
if (chartInstance.value) {
|
||||||
|
chartInstance.value.dispose();
|
||||||
|
chartInstance.value = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!chartInstance.value)
|
||||||
|
chartInstance.value = echarts.init(chartContainer.value);
|
||||||
|
setupFn(chartInstance.value, d);
|
||||||
|
show.value = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 订阅
|
||||||
|
store.$subscribe((mutation, state) => {
|
||||||
|
const d = loadData(state.data2.dailyTarget);
|
||||||
|
// const d = loadData([
|
||||||
|
// {
|
||||||
|
// targetProduction: 100,
|
||||||
|
// nowProduction: 66,
|
||||||
|
// targetYield: 13,
|
||||||
|
// nowYield: 3,
|
||||||
|
// },
|
||||||
|
// ]);
|
||||||
|
if (!d) {
|
||||||
|
show.value = false;
|
||||||
|
if (chartInstance.value) {
|
||||||
|
chartInstance.value.dispose();
|
||||||
|
chartInstance.value = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!chartInstance.value)
|
||||||
|
chartInstance.value = echarts.init(chartContainer.value);
|
||||||
|
setupFn(chartInstance.value, d);
|
||||||
|
show.value = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// utils
|
||||||
|
function loadData(dailyTarget) {
|
||||||
|
if (
|
||||||
|
dailyTarget == undefined ||
|
||||||
|
// dailyTarget?.length == 0 ||
|
||||||
|
!dailyTarget[0]
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
targetProduction: dailyTarget[0].targetProduction,
|
||||||
|
nowProduction: dailyTarget[0].nowProduction,
|
||||||
|
targetYield: dailyTarget[0].targetYield,
|
||||||
|
nowYield: dailyTarget[0].nowYield,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Container class="chart" title="本日生产线情况" icon="cube">
|
||||||
|
<div
|
||||||
|
ref="chartContainer"
|
||||||
|
class="chart-chart"
|
||||||
|
:style="{ opacity: show ? 1 : 0 }"
|
||||||
|
></div>
|
||||||
|
<p v-show="!show" class="empty-data-hint">暂无数据</p>
|
||||||
|
</Container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.chart {
|
||||||
|
/* height: 300px; */
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-chart {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,43 +1,47 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, nextTick } from "vue";
|
import { ref, onMounted, nextTick } from "vue";
|
||||||
import * as echarts from "echarts";
|
|
||||||
import Container from "../Base/Container.vue";
|
import Container from "../Base/Container.vue";
|
||||||
import { useWsStore } from "../../store";
|
import { useWsStore } from "../../store";
|
||||||
import setupFn from "./LineTodayOptions";
|
import YieldChart from "../Chart/YieldChart.vue";
|
||||||
|
import RateChart from "../Chart/RateChart.vue";
|
||||||
|
|
||||||
const show = ref(false);
|
const displayProductionChart = ref(false);
|
||||||
const chartContainer = ref(null);
|
const displayRateChart = ref(false);
|
||||||
const chartInstance = ref(null);
|
const websocketData = ref(null);
|
||||||
|
const refreshToken = ref(1);
|
||||||
const store = useWsStore();
|
const store = useWsStore();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
chartContainer.value.classList.add("h-full");
|
// websocketData.value = loadData([
|
||||||
const d = loadData(store.data2.dailyTarget);
|
|
||||||
// const d = loadData([
|
|
||||||
// {
|
// {
|
||||||
// targetProduction: 100,
|
// targetProduction: 1220,
|
||||||
// nowProduction: 66,
|
// nowProduction: 8,
|
||||||
// targetYield: 13,
|
// targetYield: null,
|
||||||
// nowYield: 3,
|
// nowYield: null,
|
||||||
// },
|
// },
|
||||||
// ]);
|
// ]);
|
||||||
if (!d) {
|
websocketData.value = loadData(store.data2.dailyTarget);
|
||||||
show.value = false;
|
if (!websocketData.value) {
|
||||||
if (chartInstance.value) {
|
displayProductionChart.value = false;
|
||||||
chartInstance.value.dispose();
|
displayRateChart.value = false;
|
||||||
chartInstance.value = null;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!chartInstance.value)
|
/** 阻止 targetProduction == 0 */
|
||||||
chartInstance.value = echarts.init(chartContainer.value);
|
if (!websocketData.value.targetProduction) {
|
||||||
setupFn(chartInstance.value, d);
|
displayProductionChart.value = false;
|
||||||
show.value = true;
|
} else {
|
||||||
|
displayProductionChart.value = true;
|
||||||
|
}
|
||||||
|
/** 阻止 targetYield == 0 */
|
||||||
|
if (!websocketData.value.targetYield) {
|
||||||
|
displayRateChart.value = false;
|
||||||
|
} else {
|
||||||
|
displayRateChart.value = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 订阅
|
// 订阅
|
||||||
store.$subscribe((mutation, state) => {
|
store.$subscribe((mutation, state) => {
|
||||||
const d = loadData(state.data2.dailyTarget);
|
|
||||||
// const d = loadData([
|
// const d = loadData([
|
||||||
// {
|
// {
|
||||||
// targetProduction: 100,
|
// targetProduction: 100,
|
||||||
@@ -46,34 +50,44 @@ store.$subscribe((mutation, state) => {
|
|||||||
// nowYield: 3,
|
// nowYield: 3,
|
||||||
// },
|
// },
|
||||||
// ]);
|
// ]);
|
||||||
if (!d) {
|
websocketData.value = loadData(state.data2.dailyTarget);
|
||||||
show.value = false;
|
if (!websocketData.value) {
|
||||||
if (chartInstance.value) {
|
displayProductionChart.value = false;
|
||||||
chartInstance.value.dispose();
|
displayRateChart.value = false;
|
||||||
chartInstance.value = null;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!chartInstance.value)
|
/** 阻止 targetProduction == 0 */
|
||||||
chartInstance.value = echarts.init(chartContainer.value);
|
if (!websocketData.value.targetProduction) {
|
||||||
setupFn(chartInstance.value, d);
|
displayProductionChart.value = false;
|
||||||
show.value = true;
|
} else {
|
||||||
|
if (refreshToken.value > 100000) refreshToken.value = 0;
|
||||||
|
refreshToken.value += 1;
|
||||||
|
displayProductionChart.value = true;
|
||||||
|
}
|
||||||
|
/** 阻止 targetYield == 0 */
|
||||||
|
if (!websocketData.value.targetYield) {
|
||||||
|
displayRateChart.value = false;
|
||||||
|
} else {
|
||||||
|
if (refreshToken.value > 100000) refreshToken.value = 0;
|
||||||
|
refreshToken.value += 1;
|
||||||
|
displayRateChart.value = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// utils
|
// utils
|
||||||
function loadData(dailyTarget) {
|
function loadData(dailyTarget) {
|
||||||
if (
|
if (dailyTarget == undefined || !dailyTarget[0]) {
|
||||||
dailyTarget == undefined ||
|
|
||||||
// dailyTarget?.length == 0 ||
|
|
||||||
!dailyTarget[0]
|
|
||||||
) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
// 目标产量
|
||||||
targetProduction: dailyTarget[0].targetProduction,
|
targetProduction: dailyTarget[0].targetProduction,
|
||||||
|
// 当前产量
|
||||||
nowProduction: dailyTarget[0].nowProduction,
|
nowProduction: dailyTarget[0].nowProduction,
|
||||||
|
// 目标成品率
|
||||||
targetYield: dailyTarget[0].targetYield,
|
targetYield: dailyTarget[0].targetYield,
|
||||||
|
// 当前成品率
|
||||||
nowYield: dailyTarget[0].nowYield,
|
nowYield: dailyTarget[0].nowYield,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -81,12 +95,38 @@ function loadData(dailyTarget) {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Container class="chart" title="本日生产线情况" icon="cube">
|
<Container class="chart" title="本日生产线情况" icon="cube">
|
||||||
<div
|
<!-- <div
|
||||||
ref="chartContainer"
|
ref="chartContainer"
|
||||||
class="chart-chart"
|
class="chart-chart"
|
||||||
:style="{ opacity: show ? 1 : 0 }"
|
:style="{ opacity: show ? 1 : 0 }"
|
||||||
></div>
|
></div>
|
||||||
<p v-show="!show" class="empty-data-hint">暂无数据</p>
|
<p v-show="!show" class="empty-data-hint">暂无数据</p> -->
|
||||||
|
<div class="container-body__h-full">
|
||||||
|
<yield-chart
|
||||||
|
:key="refreshToken + '_yield_chart_linetoday'"
|
||||||
|
:raw-data="websocketData"
|
||||||
|
/>
|
||||||
|
<rate-chart
|
||||||
|
:display-placeholder="!displayRateChart"
|
||||||
|
:key="refreshToken + '_rate_chart_linetoday'"
|
||||||
|
:raw-data="websocketData"
|
||||||
|
:isOnlyChild="!displayProductionChart"
|
||||||
|
/>
|
||||||
|
<!-- <p
|
||||||
|
v-if="!displayProductionChart && !displayRateChart"
|
||||||
|
style="
|
||||||
|
height: 100%;
|
||||||
|
line-height: 350px;
|
||||||
|
user-select: none;
|
||||||
|
flex: 1;
|
||||||
|
color: #fffc;
|
||||||
|
font-size: 24px;
|
||||||
|
text-align: center;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p> -->
|
||||||
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -99,4 +139,10 @@ function loadData(dailyTarget) {
|
|||||||
.chart-chart {
|
.chart-chart {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container-body__h-full {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ const setupFn = (chart, datalist = [0.0, 0.0, 0.0, 0.0]) => {
|
|||||||
axisLabel: {
|
axisLabel: {
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
|
rotate: 32,
|
||||||
|
margin: 12
|
||||||
},
|
},
|
||||||
splitLine: {
|
splitLine: {
|
||||||
show: true,
|
show: true,
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ const setupFn = (chart, datalist = [0.0, 0.0, 0.0, 0.0]) => {
|
|||||||
axisLabel: {
|
axisLabel: {
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
|
rotate: 32,
|
||||||
|
margin: 12
|
||||||
},
|
},
|
||||||
splitLine: {
|
splitLine: {
|
||||||
show: true,
|
show: true,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const pinia = createPinia();
|
|||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}, 24 * 60 * 60 * 1000);
|
}, 60 * 60 * 1000);
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
app.use(pinia);
|
app.use(pinia);
|
||||||
|
|||||||
1333
src/pages/3D.vue
1333
src/pages/3D.vue
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,7 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
|
|
||||||
.data-list {
|
.data-list {
|
||||||
height: 100%;
|
/* height: 100%; */
|
||||||
width: 480px;
|
width: 480px;
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export const useSettings = defineStore("settings", () => {
|
|||||||
},
|
},
|
||||||
carousel: true,
|
carousel: true,
|
||||||
carouselTime: 30, // s
|
carouselTime: 30, // s
|
||||||
|
carouselPages: ["3d", "data", "realtime", "alert", "announcement"],
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
eqStatus: true,
|
eqStatus: true,
|
||||||
}
|
}
|
||||||
@@ -70,6 +71,20 @@ export const useSettings = defineStore("settings", () => {
|
|||||||
settings.value.resolution.height = value.height;
|
settings.value.resolution.height = value.height;
|
||||||
settings.value.resolution.width = value.width;
|
settings.value.resolution.width = value.width;
|
||||||
break;
|
break;
|
||||||
|
case "carousel-page":
|
||||||
|
const exists = settings.value.carouselPages.includes(value);
|
||||||
|
if (exists)
|
||||||
|
settings.value.carouselPages = settings.value.carouselPages.filter(
|
||||||
|
(page) => page !== value
|
||||||
|
);
|
||||||
|
else {
|
||||||
|
settings.value.carouselPages.splice(
|
||||||
|
["3d", "data", "realtime", "alert", "announcement"].indexOf(value),
|
||||||
|
0,
|
||||||
|
value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { settings, updateSettings, rewriteSettings };
|
return { settings, updateSettings, rewriteSettings };
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export default class Glass {
|
|||||||
this.el.style.width = size ? `${size}px` : "16px";
|
this.el.style.width = size ? `${size}px` : "16px";
|
||||||
this.el.style.height = size ? `${size}px` : "16px";
|
this.el.style.height = size ? `${size}px` : "16px";
|
||||||
this.el.style.transformOrigin = "center";
|
this.el.style.transformOrigin = "center";
|
||||||
this.el.style.transition = `all ${distance / 25}s linear`;
|
this.el.style.transition = `all ${distance / 10}s linear`;
|
||||||
this.el.style.zIndex = "100";
|
this.el.style.zIndex = "100";
|
||||||
this.el.style.pointerEvents = "none";
|
this.el.style.pointerEvents = "none";
|
||||||
// this.el.style.transform = `rotate(${angle}deg) skew(32deg, 8deg)`;
|
// this.el.style.transform = `rotate(${angle}deg) skew(32deg, 8deg)`;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export default function useWebsocket(store, path, excludePaths = []) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// const url = "ws://192.168.1.101:8082/QbMonitoring/websocket";
|
// const url = "ws://192.168.1.101:8082/QbMonitoring/websocket";
|
||||||
const url = "ws://192.168.0.33:8082/QbMonitoring/websocket";
|
const url = "ws://192.168.0.254:8082/QbMonitoring/websocket";
|
||||||
function connectPath(store, path) {
|
function connectPath(store, path) {
|
||||||
new Client(
|
new Client(
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user