Compare commits

..

11 Commits

Author SHA1 Message Date
DESKTOP-FUDKNA8\znjsz
73aa0d9f54 update std chart 2024-04-11 15:32:53 +08:00
DESKTOP-FUDKNA8\znjsz
8bd678cf62 update chip yield chart 2024-04-11 15:27:23 +08:00
DESKTOP-FUDKNA8\znjsz
11626c5142 update company info 2024-04-11 10:40:16 +08:00
DESKTOP-FUDKNA8\znjsz
d94b5fa9c3 update right chart 2024-04-11 10:16:16 +08:00
DESKTOP-FUDKNA8\znjsz
28ec95ba81 update right chart base 2024-04-10 16:27:14 +08:00
DESKTOP-FUDKNA8\znjsz
921da642b6 update fto 2024-04-10 15:39:37 +08:00
DESKTOP-FUDKNA8\znjsz
9aefc3def8 update chip invest chart 2024-04-10 15:16:14 +08:00
DESKTOP-FUDKNA8\znjsz
8d4470db21 add fullscreen 2024-04-10 14:07:42 +08:00
DESKTOP-FUDKNA8\znjsz
e2f4183d0b update chart resize 2024-04-10 13:49:56 +08:00
DESKTOP-FUDKNA8\znjsz
3ca4412f23 add icon&scrollbar 2024-04-10 09:47:45 +08:00
DESKTOP-FUDKNA8\znjsz
4c2bca6c76 add fto&chip-invest 2024-04-10 09:33:09 +08:00
15 changed files with 1526 additions and 47 deletions

View File

@ -0,0 +1,64 @@
<!--
filename: Bipv.vue
author: liubin
date: 2024-04-10 15:39:54
description:
-->
<template>
<right-chart-base
:legend="legend"
:series="series"
:xAxis="xAxis"
:vHeight="20.5"
class="bipv-chart"
/>
</template>
<script>
import RightChartBase from "./RightChartBase.vue";
export default {
name: "BipvChart",
components: { RightChartBase },
props: {
legend: {
type: Array,
default: () => [
{ label: "2024年目标值", color: "#f3c000" },
{ label: "2023年", color: "#12f7f1" },
{ label: "2024年", color: "#58adfa" },
],
},
xAxis: {
type: Array,
default: () => ["成都", "邯郸", "株洲", "瑞昌", "heels", "socks"],
},
series: {
type: Array,
default: () => [
{
name: "2024年目标值",
data: Array.from({ length: 7 }, () =>
Math.floor(Math.random() * 1000)
),
},
{
name: "2023年",
data: Array.from({ length: 7 }, () =>
Math.floor(Math.random() * 1000)
),
},
{
name: "2024年",
data: Array.from({ length: 7 }, () =>
Math.floor(Math.random() * 1000)
),
},
],
},
},
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,54 @@
<!--
filename: chip-invest.vue
author: liubin
date: 2024-04-10 08:59:28
description:
-->
<template>
<left-chart-base
:legend="legend"
:series="series"
:xAxis="xAxis"
class="chip-invest-chart"
/>
</template>
<script>
import LeftChartBase from "./LeftChartBase.vue";
export default {
name: "chip-investChart",
components: { LeftChartBase },
props: {
legend: {
type: Array,
default: () => [
{ label: "2023年", color: "#12f7f1" },
{ label: "2024年", color: "#58adfa" },
],
},
xAxis: {
type: Array,
default: () => ["成都", "邯郸", "株洲", "瑞昌", "heels", "socks"],
},
series: {
type: Array,
default: () => [
{
name: "2023年",
data: Array.from({ length: 7 }, () =>
Math.floor(Math.random() * 1000)
),
},
{
name: "2024年",
data: Array.from({ length: 7 }, () =>
Math.floor(Math.random() * 1000)
),
},
],
},
},
};
</script>

View File

@ -0,0 +1,196 @@
<!--
filename: ChipYield.vue
author: liubin
date: 2024-04-11 10:46:47
description:
-->
<template>
<div class="chip-yield">
<chip-yield-chart />
<section class="right-part">
<div class="yield-location">
<section class="btn-group">
<button
@click="activeLoc = '1'"
:class="activeLoc === '1' ? 'active' : ''"
>
成都
</button>
<button
@click="activeLoc = '2'"
:class="activeLoc === '2' ? 'active' : ''"
>
邯郸
</button>
<button
@click="activeLoc = '3'"
:class="activeLoc === '3' ? 'active' : ''"
>
株洲
</button>
<button
@click="activeLoc = '4'"
:class="activeLoc === '4' ? 'active' : ''"
>
瑞昌
</button>
</section>
<section class="btn-group">
<button
@click="activeLoc = '5'"
:class="activeLoc === '5' ? 'active' : ''"
class="fixwidth"
>
佳木斯
</button>
<button
@click="activeLoc = '6'"
:class="activeLoc === '6' ? 'active' : ''"
>
凯盛光伏
</button>
<button
@click="activeLoc = '7'"
:class="activeLoc === '7' ? 'active' : ''"
>
蚌埠兴科
</button>
</section>
</div>
<div class="yield-summary">
<div class="legend">
<span class="legend-label">2024年累计</span>
<span class="legend-value deep-green">40,100</span>
</div>
<div class="legend">
<span class="legend-label">2024年目标</span>
<span class="legend-value">30,100</span>
</div>
<div class="legend">
<span class="legend-label">2023年累计</span>
<span class="legend-value deep-blue">400</span>
</div>
</div>
</section>
</div>
</template>
<script>
import ChipYieldChart from "./ChipYieldChart.vue";
export default {
name: "ChipYield",
components: { ChipYieldChart },
props: {},
data() {
return {
activeLoc: "1",
};
},
};
</script>
<style scoped lang="scss">
.chip-yield {
height: 0;
flex: 1;
background: #c0c1;
display: flex;
gap: 12px;
.yield-location {
margin-top: 2.2vh;
.btn-group {
margin-top: 8px;
display: flex;
border-radius: 4px;
overflow: hidden;
button {
flex: 1;
appearance: none;
outline: none;
border: none;
cursor: pointer;
background: #01306c;
color: #fff;
padding: 8px 6px;
font-size: 0.63vw;
position: relative;
}
button.fixwidth {
flex: unset;
width: 2.765vw;
}
button:not(:first-child)::before {
content: "";
display: inline-block;
width: 2px;
height: 60%;
background: #052141;
position: absolute;
top: 20%;
left: -1px;
}
button.active {
background: #1d74d8;
}
}
}
.yield-summary {
margin-top: 3vh;
display: grid;
gap: 0.56vw;
grid-auto-rows: 40px;
grid-template-columns: 1fr 1fr;
.legend {
border-radius: 4px;
padding: 1px;
display: flex;
flex-direction: column;
font-size: 0.725vw;
padding-left: 0.88vw;
position: relative;
&::before {
content: "";
position: absolute;
top: 20%;
left: 0;
width: 0.52vw;
height: 0.52vw;
border-radius: 2px;
background: #ccc;
display: inline-block;
}
&:first-child::before {
background: #11f0e8;
}
&:nth-child(2)::before {
background: #003982;
}
&:last-child::before {
background: #0551c7;
}
.deep-blue {
color: #0551c7;
}
.deep-green {
color: #11f0e8;
}
}
}
}
</style>

View File

@ -0,0 +1,194 @@
<!--
filename: ChipYield.vue
author: liubin
date: 2024-04-11 10:46:47
description:
-->
<template>
<chart-container class="chip-yield-chart" :noScroll="true">
<div
ref="chart"
style="width: 10vw"
:style="{ height: vHeight + 'vh' }"
></div>
</chart-container>
</template>
<script>
import ChartContainerVue from "../components/ChartContainer.vue";
import chartMixin from "../mixins/chart.js";
import screenfull from "screenfull";
export default {
name: "ChipYield",
components: { ChartContainer: ChartContainerVue },
mixins: [chartMixin],
props: {
vHeight: {
type: Number,
default: 22,
},
},
data() {
return {
isFullscreen: false,
options: {
grid: {
left: 0,
right: 0,
bottom: 0,
top: 0,
containLabel: true,
},
tooltip: {},
title: {
text: "78%",
left: "48%",
top: "35%",
textAlign: "center",
textStyle: {
fontWeight: 600,
fontSize: 32,
color: "#fffd",
},
subtext: "\u200224年累计产出\u2002",
subtextStyle: {
fontSize: 14,
fontWeight: 100,
color: "#fffd",
align: "right",
},
},
series: [
// series - 2024
{
type: "pie",
name: "2024目标",
radius: ["70%", "85%"],
center: ["50%", "52%"],
emptyCircleStyle: {
color: "#042c5f33",
},
},
// series - 2024
{
type: "pie",
radius: ["70%", "85%"],
center: ["50%", "52%"],
avoidLabelOvervlap: false,
label: {
show: false,
// position: "center",
},
labelLine: {
show: false,
},
data: [
{
value: 90,
name: "2024累计产出",
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 },
},
],
},
// series2 - 2023
{
type: "pie",
radius: ["55%", "70%"],
center: ["50%", "52%"],
avoidLabelOvervlap: false,
label: {
show: false,
},
labelLine: {
show: false,
},
data: [
{
value: 90,
name: "2023累计产出",
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 },
},
],
},
],
},
};
},
watch: {
/** 全屏状态切换时,对柱子粗细和字体大小进行相应调整 */
isFullscreen(val) {
this.options.title.top = val ? "40%" : "35%";
this.options.title.textStyle.fontSize = val ? 48 : 32;
this.options.title.subtextStyle.fontSize = val ? 18 : 14;
this.initOptions(this.options);
},
},
mounted() {
/** 清除 MIN_WIDTH, 此处比较特殊, 需要这么一步, 去除 chart mixin 的滚动条功能 */
this.MIN_WIDTH = 0;
this.initOptions(this.options);
if (screenfull.isEnabled) {
screenfull.on("change", () => {
this.isFullscreen = screenfull.isFullscreen;
});
}
},
};
</script>
<style scoped lang="scss">
.chip-yield-chart {
height: 100%;
flex: 1;
overflow: visible;
}
</style>

View File

@ -0,0 +1,54 @@
<!--
filename: fto.vue
author: liubin
date: 2024-04-10 08:59:28
description:
-->
<template>
<left-chart-base
:legend="legend"
:series="series"
:xAxis="xAxis"
class="fto-chart"
/>
</template>
<script>
import LeftChartBase from "./LeftChartBase.vue";
export default {
name: "FtoChart",
components: { LeftChartBase },
props: {
legend: {
type: Array,
default: () => [
{ label: "2023年", color: "#12f7f1" },
{ label: "2024年", color: "#58adfa" },
],
},
xAxis: {
type: Array,
default: () => ["成都", "邯郸", "株洲", "瑞昌", "heels", "socks"],
},
series: {
type: Array,
default: () => [
{
name: "2023年",
data: Array.from({ length: 7 }, () =>
Math.floor(Math.random() * 1000)
),
},
{
name: "2024年",
data: Array.from({ length: 7 }, () =>
Math.floor(Math.random() * 1000)
),
},
],
},
},
};
</script>

View File

@ -0,0 +1,245 @@
<!--
filename: left-chart-base
author: liubin
date: 2024-04-10 08:59:28
description:
-->
<template>
<chart-container class="left-chart-base">
<div class="legend">
<span
v-for="item in legend"
:key="item.label"
class="legend-item"
:style="{ fontSize: isFullscreen ? '16px' : '12px' }"
>{{ item.label }}</span
>
</div>
<div
ref="chart"
style="max-width: 22vw"
:style="{ height: vHeight + 'vh' }"
></div>
</chart-container>
</template>
<script>
import screenfull from "screenfull";
import ChartContainerVue from "../components/ChartContainer.vue";
import chartMixin from "../mixins/chart.js";
export default {
name: "LeftChartBase",
components: {
ChartContainer: ChartContainerVue,
},
mixins: [chartMixin],
props: {
vHeight: {
type: Number,
default: 34,
},
legend: {
type: Array,
required: true,
},
xAxis: {
type: Array,
required: true,
},
series: {
type: Array,
required: true,
},
},
data() {
return {
isFullscreen: false,
options: {
grid: {
left: "3%",
right: "4%",
bottom: "0",
top: "15%",
containLabel: true,
},
tooltip: {},
xAxis: {
axisTick: {
show: false,
},
axisLine: {
lineStyle: {
color: "#4561AE",
},
},
axisLabel: {
color: "#fff",
fontSize: 12,
},
data: this.xAxis,
},
yAxis: {
name: "单位/片",
nameTextStyle: {
color: "#fff",
fontSize: 12,
},
axisTick: {
show: false,
},
axisLabel: {
color: "#fff",
fontSize: 12,
},
axisLine: {
show: true,
lineStyle: {
color: "#4561AE",
},
},
splitLine: {
lineStyle: {
color: "#4561AE",
},
},
},
series: [
{
name: "2023年",
type: "bar",
barWidth: 12,
itemStyle: {
borderRadius: [10, 10, 0, 0],
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#12f7f1", // 0%
},
{
offset: 0.35,
color: "#12f7f177", // 100%
},
{
offset: 0.75,
color: "#12f7f133", // 100%
},
{
offset: 1,
color: "transparent", // 100%
},
],
global: false, // false
},
},
data: this.series[0].data,
},
{
name: "2024年",
type: "bar",
barWidth: 12,
// tooltip: {
// valueFormatter: function (value) {
// return value + " ml";
// },
// },
itemStyle: {
borderRadius: [10, 10, 0, 0],
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#57abf8", // 0%
},
{
offset: 1,
color: "#364BFE66", // 100%
},
],
global: false, // false
},
},
data: this.series[1].data,
},
],
},
};
},
watch: {
/** 全屏状态切换时,对柱子粗细和字体大小进行相应调整 */
isFullscreen(val) {
this.options.series.map((item) => {
item.barWidth = val ? 18 : 12;
});
this.options.xAxis.axisLabel.fontSize = val ? 18 : 12;
this.options.yAxis.axisLabel.fontSize = val ? 18 : 12;
this.options.yAxis.nameTextStyle.fontSize = val ? 18 : 12;
this.initOptions(this.options);
},
},
mounted() {
this.initOptions(this.options);
if (screenfull.isEnabled) {
screenfull.on("change", () => {
this.isFullscreen = screenfull.isFullscreen;
});
}
},
};
</script>
<style scoped lang="scss">
.left-chart-base {
// position: relative;
.legend {
position: absolute;
top: 5.2vh;
right: 1vw;
}
.legend-item {
position: relative;
font-size: 12px;
margin-right: 0.67vw;
&::before {
content: "";
display: inline-block;
// width: 10px;
// height: 10px;
width: 0.531vw;
height: 0.531vw;
background-color: #ccc;
border-radius: 2px;
margin-right: 0.22vw;
}
}
.legend-item:nth-child(1):before {
background-color: #12f7f1;
}
.legend-item:nth-child(2):before {
background-color: #58adfa;
}
/** add more */
// .legend-item:nth-child(3):before {
// background-color: #f7f1;
// }
}
</style>

View File

@ -0,0 +1,308 @@
<!--
filename: right-chart-base
author: liubin
date: 2024-04-10 08:59:28
description:
-->
<template>
<chart-container class="right-chart-base">
<div class="legend">
<span
v-for="item in legend"
:key="item.label"
class="legend-item"
:style="{ fontSize: isFullscreen ? '16px' : '12px' }"
>{{ item.label }}</span
>
</div>
<div
ref="chart"
style="max-width: 22vw"
:style="{ height: vHeight + 'vh' }"
></div>
</chart-container>
</template>
<script>
import screenfull from "screenfull";
import ChartContainerVue from "../components/ChartContainer.vue";
import chartMixin from "../mixins/chart.js";
export default {
name: "RightChartBase",
components: {
ChartContainer: ChartContainerVue,
},
mixins: [chartMixin],
props: {
vHeight: {
type: Number,
default: 34,
},
legend: {
type: Array,
required: true,
},
xAxis: {
type: Array,
required: true,
},
series: {
type: Array,
required: true,
},
},
data() {
return {
isFullscreen: false,
options: {
grid: {
left: "3%",
right: "4%",
bottom: "0",
top: "18%",
containLabel: true,
},
tooltip: {},
xAxis: {
axisTick: {
show: false,
},
axisLine: {
lineStyle: {
color: "#4561AE",
},
},
axisLabel: {
color: "#fff",
fontSize: 12,
},
data: this.xAxis,
},
yAxis: {
name: "单位/片",
nameTextStyle: {
color: "#fff",
fontSize: 12,
},
axisTick: {
show: false,
},
axisLabel: {
color: "#fff",
fontSize: 12,
},
axisLine: {
show: true,
lineStyle: {
color: "#4561AE",
},
},
splitLine: {
lineStyle: {
color: "#4561AE",
},
},
},
series: [
{
name: "2024年目标值",
type: "line",
lineStyle: {
color: "#f3c000",
},
itemStyle: {
color: "#f3c000",
},
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#f3c000", // 0%
},
{
offset: 0.55,
color: "#f3c00033",
},
{
offset: 1,
color: "transparent", // 100%
},
],
global: false, // false
},
},
data: this.series[0].data,
},
{
name: "2023年",
type: "bar",
barWidth: 12,
itemStyle: {
borderRadius: [10, 10, 0, 0],
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#12f7f1", // 0%
},
{
offset: 0.35,
color: "#12f7f177", // 100%
},
{
offset: 0.75,
color: "#12f7f133", // 100%
},
{
offset: 1,
color: "transparent", // 100%
},
],
global: false, // false
},
},
data: this.series[1].data,
},
{
name: "2024年",
type: "bar",
barWidth: 12,
// tooltip: {
// valueFormatter: function (value) {
// return value + " ml";
// },
// },
itemStyle: {
borderRadius: [10, 10, 0, 0],
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#57abf8", // 0%
},
{
offset: 1,
color: "#364BFE66", // 100%
},
],
global: false, // false
},
},
data: this.series[2].data,
},
],
},
};
},
watch: {
/** 全屏状态切换时,对柱子粗细和字体大小进行相应调整 */
isFullscreen(val) {
this.options.series.map((item) => {
item.barWidth = val ? 18 : 12;
});
this.options.xAxis.axisLabel.fontSize = val ? 18 : 12;
this.options.yAxis.axisLabel.fontSize = val ? 18 : 12;
this.options.yAxis.nameTextStyle.fontSize = val ? 18 : 12;
this.initOptions(this.options);
},
},
mounted() {
this.initOptions(this.options);
if (screenfull.isEnabled) {
screenfull.on("change", () => {
this.isFullscreen = screenfull.isFullscreen;
});
}
},
};
</script>
<style scoped lang="scss">
.right-chart-base {
// position: relative;
.legend {
position: absolute;
top: 5.2vh;
right: 1vw;
}
.legend-item {
position: relative;
font-size: 12px;
margin-right: 0.67vw;
&::before {
content: "";
display: inline-block;
// width: 10px;
// height: 10px;
width: 0.531vw;
height: 0.531vw;
background-color: #ccc;
border-radius: 2px;
margin-right: 0.22vw;
}
}
.legend-item:nth-child(1):before {
// width: 12px;
// height: 2px;
width: 0.638vw;
height: 0.1064vw;
background-color: #f3c000;
position: absolute;
top: 50%;
// left: -16px;
left: -0.851vw;
transform: translateY(-50%);
}
.legend-item:nth-child(1):after {
background-color: #f3c000;
content: "";
display: inline-block;
position: absolute;
// width: 6px;
// height: 6px;
width: 0.3191vw;
height: 0.3191vw;
border-radius: 100%;
top: 50%;
left: -0.851vw;
// left: -16px;
transform: translateY(-50%) translateX(50%);
}
.legend-item:nth-child(2):before {
background-color: #12f7f1;
}
.legend-item:nth-child(3):before {
background-color: #58adfa;
}
/** add more */
// .legend-item:nth-child(3):before {
// background-color: #f7f1;
// }
}
</style>

View File

@ -0,0 +1,64 @@
<!--
filename: Bipv.vue
author: liubin
date: 2024-04-10 15:39:54
description:
-->
<template>
<right-chart-base
:legend="legend"
:series="series"
:xAxis="xAxis"
:vHeight="20.5"
class="std-chart"
/>
</template>
<script>
import RightChartBase from "./RightChartBase.vue";
export default {
name: "StdChart",
components: { RightChartBase },
props: {
legend: {
type: Array,
default: () => [
{ label: "2024年目标值", color: "#f3c000" },
{ label: "2023年", color: "#12f7f1" },
{ label: "2024年", color: "#58adfa" },
],
},
xAxis: {
type: Array,
default: () => ["成都", "邯郸", "株洲", "瑞昌", "heels", "socks"],
},
series: {
type: Array,
default: () => [
{
name: "2024年目标值",
data: Array.from({ length: 7 }, () =>
Math.floor(Math.random() * 1000)
),
},
{
name: "2023年",
data: Array.from({ length: 7 }, () =>
Math.floor(Math.random() * 1000)
),
},
{
name: "2024年",
data: Array.from({ length: 7 }, () =>
Math.floor(Math.random() * 1000)
),
},
],
},
},
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,69 @@
<!--
filename: ChartContainer.vue
author: liubin
date: 2024-04-10 08:54:33
description:
todo: 实现滑动条 和动态宽高
-->
<template>
<div class="chart-container" :class="{ 'no-scroll': noScroll }">
<slot />
</div>
</template>
<script>
export default {
name: "ChartContainer",
components: {},
props: {
noScroll: {
type: Boolean,
default: false,
},
},
data() {
return {};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss">
.chart-container {
height: 0;
flex: 1;
overflow-x: scroll;
}
.no-scroll::-webkit-scrollbar {
width: 0;
height: 0;
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-button {
width: 0;
height: 0;
// width: 10px;
// height: 10px;
// background: #14305f;
}
::-webkit-scrollbar-track {
background: #14305f;
border: 0 none;
border-radius: 0;
}
::-webkit-scrollbar-thumb {
background: #004798;
border: 0 none;
border-radius: 6px;
}
</style>

View File

@ -12,7 +12,7 @@
<h2>{{ info.companyName }}</h2> <h2>{{ info.companyName }}</h2>
<ul> <ul>
<li v-for="item in info.items" :key="item.label"> <li v-for="item in info.items" :key="item.label">
{{ item.label }} {{ item.value }} {{ item.label }} {{ item.value | currency }}
</li> </li>
</ul> </ul>
</div> </div>
@ -34,6 +34,11 @@ export default {
default: () => ({ x: 0, y: 0 }), default: () => ({ x: 0, y: 0 }),
}, },
}, },
filters: {
currency(value) {
return value.toLocaleString();
},
},
data() { data() {
return {}; return {};
}, },

View File

@ -25,7 +25,9 @@
:class="[ :class="[
side == 'left' ? 'body-gradient-to-right' : 'body-gradient-to-left', side == 'left' ? 'body-gradient-to-right' : 'body-gradient-to-left',
]" ]"
></div> >
<slot />
</div>
</div> </div>
</template> </template>
@ -60,10 +62,25 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.dashboard-container { .dashboard-container {
height: 0;
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: relative; position: relative;
box-shadow: inset 0 0 20px 1px #fff1;
// &::after {
// content: "";
// position: absolute;
// display: inline-block;
// width: 60%;
// height: 0.31415vh;
// border-radius: 2px;
// left: 8%;
// bottom: 0;
// background: linear-gradient(to right, #024798, transparent);
// z-index: 0;
// }
.container-head { .container-head {
// height: 40px; // height: 40px;
@ -82,9 +99,11 @@ export default {
} }
.container-body { .container-body {
padding: 8px; padding: 12px;
display: flex; display: flex;
flex-direction: column;
flex: 1; flex: 1;
height: 0;
} }
.corner { .corner {

View File

@ -6,18 +6,43 @@
--> -->
<template> <template>
<div class="container-icon"></div> <div class="container-icon" :style="bgStyle"></div>
</template> </template>
<script> <script>
import cube from "@/assets/images/homeindex/fto-icon.png";
import chip from "@/assets/images/homeindex/chip-icon.png";
import chip2 from "@/assets/images/homeindex/chip-icon-2.png";
import bipv from "@/assets/images/homeindex/bipv-icon.png";
import std from "@/assets/images/homeindex/std-icon.png";
export default { export default {
name: "ContainerIcon", name: "ContainerIcon",
components: {}, components: {},
props: {}, props: {
icon: {
type: String,
default: "cube",
},
},
data() { data() {
return {}; return {};
}, },
computed: {}, computed: {
bgStyle() {
return {
cube:
"background: url(" + cube + ") no-repeat center center / 100% 100%",
chip:
"background: url(" + chip + ") no-repeat center center / 100% 100%",
chip2:
"background: url(" + chip2 + ") no-repeat center center / 100% 100%",
bipv:
"background: url(" + bipv + ") no-repeat center center / 100% 100%",
std: "background: url(" + std + ") no-repeat center center / 100% 100%",
}[this.icon];
},
},
methods: {}, methods: {},
}; };
</script> </script>

View File

@ -7,6 +7,7 @@
<template> <template>
<header class="dashboard-header"> <header class="dashboard-header">
<div class="btn" :style="btnStyle" @click="toggleFullscreen"></div>
<h1>发电玻璃智能管控平台地图总览</h1> <h1>发电玻璃智能管控平台地图总览</h1>
<span class="side left">晴转多云 14</span> <span class="side left">晴转多云 14</span>
<span class="side right">23:12|星期一|2023.12.13</span> <span class="side right">23:12|星期一|2023.12.13</span>
@ -14,15 +15,38 @@
</template> </template>
<script> <script>
import screenfull from "screenfull";
import fullscreenIcon from "@/assets/images/homeindex/fullscreen.png";
import fullscreenExitIcon from "@/assets/images/homeindex/exit-fullscreen.png";
export default { export default {
name: "DashboardHeader", name: "DashboardHeader",
components: {}, components: {},
props: {}, props: {},
data() { data() {
return {}; return {
isFullscreen: false,
};
},
computed: {
btnStyle() {
return {
backgroundImage: `url(${
this.isFullscreen ? fullscreenExitIcon : fullscreenIcon
})`,
};
},
},
methods: {
toggleFullscreen() {
screenfull.toggle();
this.isFullscreen = !this.isFullscreen;
//
const el = document.querySelector(".dashboard-factory-all");
el.style.width = this.isFullscreen ? "100vw" : "calc(100vw - 54px)";
el.style.left = this.isFullscreen ? "0" : "54px";
},
}, },
computed: {},
methods: {},
}; };
</script> </script>
@ -34,6 +58,17 @@ export default {
position: relative; position: relative;
display: grid; display: grid;
place-content: center; place-content: center;
.btn {
cursor: pointer;
position: absolute;
width: 2vw;
height: 2vw;
top: 50%;
right: 1.18vw;
background-size: 100% 100%;
background-position: 0 0;
}
} }
h1 { h1 {
@ -49,18 +84,19 @@ h1 {
.side { .side {
position: absolute; position: absolute;
font-size: 1.18vw; font-size: 1.18vw;
line-height: 24px; // line-height: 24px;
line-height: 1.277vw;
letter-spacing: 2px; letter-spacing: 2px;
color: #69b4ff; color: #69b4ff;
} }
.left { .left {
left: 22vw; left: 22vw;
top: 4.65vh; top: 4.9vh;
} }
.right { .right {
right: 15vw; right: 15vw;
top: 4.65vh; top: 4.9vh;
} }
</style> </style>

View File

@ -0,0 +1,101 @@
import * as echarts from "echarts";
function __resizeHandler(entries) {
for (const entry of entries) {
if (entry.contentBoxSize) {
// manipulate contentBoxSize
const contentBoxSize = Array.isArray(entry.contentBoxSize)
? entry.contentBoxSize[0]
: entry.contentBoxSize;
this.chart_mixin_chartInstance.resize({
width:
contentBoxSize.inlineSize < this.MIN_WIDTH
? this.MIN_WIDTH
: contentBoxSize.inlineSize,
height: contentBoxSize.blockSize,
});
} else {
// manipulate contentRect
this.chart_mixin_chartInstance.resize({
width:
entry.contentRect.width < this.MIN_WIDTH
? this.MIN_WIDTH
: entry.contentRect.width,
height: entry.contentRect.height,
});
}
}
}
export default {
data() {
const resizeObserver = new ResizeObserver(__resizeHandler.bind(this));
return {
MIN_WIDTH: 400,
chart_mixin_chartInstance: null,
chart_mixin_observer: resizeObserver,
chart_mixin_options: {
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
tooltip: {},
legend: {
data: ["Sales"],
},
xAxis: {
data: [
"shirt",
"cardign",
"chiffon shirt",
"pants",
"heels",
"socks",
],
},
yAxis: {},
series: [
{
name: "Sales",
type: "bar",
data: [5, 20, 36, 10, 10, 20],
},
],
},
};
},
mounted() {
// this.$nextTick(() => {
// this.initChart().then(() => {
// this.initOptions(this.chart_mixin_options);
// this.initListener();
// });
// });
this.initChart();
this.initListener();
},
methods: {
initChart() {
(this.$refs.chart ||
console.warn('[mixins/chart] 注意是否有 ref="chart" 的元素存在')) &&
(this.chart_mixin_chartInstance = echarts.init(this.$refs.chart));
// return new Promise((resolve, reject) => {
// this.$refs.chart ? resolve(true) : reject(false);
// });
},
initOptions(options) {
this.chart_mixin_chartInstance.setOption(options);
},
initListener() {
this.chart_mixin_observer.observe(this.$refs.chart);
},
},
beforeDestroy() {
if (this.chart_mixin_chartInstance) {
this.chart_mixin_chartInstance.dispose();
}
},
};

View File

@ -5,13 +5,27 @@
<db-header class="db-header"></db-header> <db-header class="db-header"></db-header>
<div class="db-body"> <div class="db-body">
<div class="db-left"> <div class="db-left">
<db-container icon="cube" title="FTO投入"></db-container> <db-container icon="cube" title="FTO投入">
<db-container icon="chip" title="芯片投入"></db-container> <fto-chart />
</db-container>
<db-container icon="chip2" title="芯片投入">
<chip-invest-chart />
</db-container>
</div> </div>
<div class="db-right"> <div class="db-right">
<db-container side="right" icon="chip2" title="芯片产出"></db-container> <db-container side="right" icon="chip" title="芯片产出">
<db-container side="right" icon="std" title="标准组件产出"></db-container> <chip-yield-chart />
<db-container side="right" icon="stack" title="BIPV产出"></db-container> </db-container>
<db-container
side="right"
icon="std"
title="标准组件产出"
>
<std-chart />
</db-container>
<db-container side="right" icon="bipv" title="BIPV产出">
<bipv-chart />
</db-container>
</div> </div>
</div> </div>
</div> </div>
@ -30,6 +44,27 @@ import store from "@/store";
import DashboardHeader from "./dashboard/components/Header.vue"; import DashboardHeader from "./dashboard/components/Header.vue";
import CompanyInfo from "./dashboard/components/CompanyInfo.vue"; import CompanyInfo from "./dashboard/components/CompanyInfo.vue";
import Container from "./dashboard/components/Container.vue"; import Container from "./dashboard/components/Container.vue";
import ChartContainer from "./dashboard/components/ChartContainer.vue";
import FtoChart from "./dashboard/charts/Fto.vue";
import ChipInvestChart from "./dashboard/charts/ChipInvest.vue";
import BipvChart from "./dashboard/charts/Bipv.vue";
import ChipYieldChart from "./dashboard/charts/ChipYield.vue";
import StdChart from "./dashboard/charts/StdChart.vue";
const LOCATIONS = [
//
{ x: 67, y: 20 },
//
{ x: 46, y: 56 },
// 1
{ x: 60, y: 52 },
// 2
{ x: 61, y: 53 },
// 西
{ x: 60, y: 58 },
//
{ x: 56, y: 60 },
];
export default { export default {
name: "Index", name: "Index",
@ -37,6 +72,12 @@ export default {
CompanyInfo, CompanyInfo,
DbHeader: DashboardHeader, DbHeader: DashboardHeader,
DbContainer: Container, DbContainer: Container,
ChartContainer,
FtoChart,
ChipInvestChart,
ChipYieldChart,
BipvChart,
StdChart,
}, },
data() { data() {
return { return {
@ -59,26 +100,13 @@ export default {
}, },
methods: { methods: {
initPins() { initPins() {
[ LOCATIONS.map((loc) => {
//
{ x: 67, y: 20 },
//
{ x: 46, y: 56 },
// 1
{ x: 60, y: 52 },
// 2
{ x: 61, y: 53 },
// 西
{ x: 60, y: 58 },
//
{ x: 56, y: 60 },
].map((loc) => {
const pin = document.createElement("div"); const pin = document.createElement("div");
pin.className = "pin"; pin.className = "pin";
pin.style.left = `${loc.x}%`; pin.style.left = `${loc.x}%`;
pin.style.top = `${loc.y}%`; pin.style.top = `${loc.y}%`;
pin.addEventListener("mouseenter", () => { pin.addEventListener("mouseenter", () => {
this.showHint({ x: loc.x, y: loc.y }); this.showHint(loc);
}); });
pin.addEventListener("mouseleave", () => { pin.addEventListener("mouseleave", () => {
this.closeHint(); this.closeHint();
@ -92,21 +120,32 @@ export default {
}, },
showHint(position) { showHint(position) {
this.hintPosition = position; this.hintPosition = position;
this.info = { const templateInfo = {
// companyName: "", companyName: "",
companyName: "蚌埠兴科玻璃有限公司",
// companyName: "",
// companyName: "",
// companyName: "",
// companyName: "",
// companyName: "",
items: [ items: [
{ label: "FTO投入", value: "1,200" }, { label: "FTO投入", value: Math.floor(Math.random() * 1000000) },
{ label: "芯片产出", value: "2,200" }, { label: "芯片产出", value: Math.floor(Math.random() * 10000000) },
{ label: "芯片投入", value: "1,300" }, { label: "芯片投入", value: Math.floor(Math.random() * 1000000) },
{ label: "标准组件产出", value: "1,100" }, { label: "标准组件产出", value: Math.floor(Math.random() * 1000000) },
], ],
}; };
if (position === LOCATIONS[0]) {
templateInfo.companyName = "佳木斯中建材光电材料有限公司";
} else if (position === LOCATIONS[1]) {
templateInfo.companyName = "成都中建材光电材料有限公司";
} else if (position === LOCATIONS[2]) {
templateInfo.companyName = "蚌埠兴科玻璃有限公司";
} else if (position === LOCATIONS[3]) {
templateInfo.companyName = "凯盛光伏材料有限公司(本部)";
} else if (position === LOCATIONS[4]) {
templateInfo.companyName = "瑞昌中建材光电材料有限公司";
} else if (position === LOCATIONS[5]) {
templateInfo.companyName = "中建材(株洲)光电材料有限公司";
}
this.info = templateInfo;
this.$nextTick(() => { this.$nextTick(() => {
this.visible = true; this.visible = true;
}); });
@ -115,6 +154,13 @@ export default {
}; };
</script> </script>
<style>
.hideSidebar.mobile .dashboard-factory-all {
left: 0 !important;
width: 100vw !important;
}
</style>
<style lang="scss" scoped> <style lang="scss" scoped>
.dashboard-factory-all { .dashboard-factory-all {
background: #151516; background: #151516;
@ -123,7 +169,7 @@ export default {
left: 54px; left: 54px;
height: 100vh; height: 100vh;
width: calc(100vw - 54px); width: calc(100vw - 54px);
z-index: 1000; z-index: 1001;
color: #fff; color: #fff;
} }
@ -138,7 +184,6 @@ export default {
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: #15151633;
z-index: 1; z-index: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;