增加模块

This commit is contained in:
TS-QD1 2023-11-21 17:48:18 +08:00
parent 0140c55ebb
commit 0c4ca76328
22 changed files with 543 additions and 49 deletions

64
package-lock.json generated
View File

@ -9,8 +9,10 @@
"version": "0.0.0",
"dependencies": {
"echarts": "^5.4.3",
"echarts-gl": "^2.0.9",
"stylus": "^0.61.0",
"vue": "^3.3.8"
"vue": "^3.3.8",
"vue3-seamless-scroll": "^2.0.1"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.5.0",
@ -675,6 +677,11 @@
"concat-map": "0.0.1"
}
},
"node_modules/claygl": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/claygl/-/claygl-1.3.0.tgz",
"integrity": "sha512-+gGtJjT6SSHD2l2yC3MCubW/sCV40tZuSs5opdtn79vFSGUgp/lH139RNEQ6Jy078/L0aV8odCw8RSrUcMfLaQ=="
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -710,6 +717,18 @@
"zrender": "5.4.4"
}
},
"node_modules/echarts-gl": {
"version": "2.0.9",
"resolved": "https://registry.npmmirror.com/echarts-gl/-/echarts-gl-2.0.9.tgz",
"integrity": "sha512-oKeMdkkkpJGWOzjgZUsF41DOh6cMsyrGGXimbjK2l6Xeq/dBQu4ShG2w2Dzrs/1bD27b2pLTGSaUzouY191gzA==",
"dependencies": {
"claygl": "^1.2.1",
"zrender": "^5.1.1"
},
"peerDependencies": {
"echarts": "^5.1.2"
}
},
"node_modules/esbuild": {
"version": "0.19.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz",
@ -966,6 +985,14 @@
"url": "https://opencollective.com/stylus"
}
},
"node_modules/throttle-debounce": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.0.tgz",
"integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==",
"engines": {
"node": ">=12.22"
}
},
"node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
@ -1046,6 +1073,14 @@
}
}
},
"node_modules/vue3-seamless-scroll": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/vue3-seamless-scroll/-/vue3-seamless-scroll-2.0.1.tgz",
"integrity": "sha512-mI3BaDU3pjcPUhVSw3/xNKdfPBDABTi/OdZaZqKysx4cSdNfGRbVvGNDzzptBbJ5S7imv5T55l6x/SqgnxKreg==",
"dependencies": {
"throttle-debounce": "5.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@ -1434,6 +1469,11 @@
"concat-map": "0.0.1"
}
},
"claygl": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/claygl/-/claygl-1.3.0.tgz",
"integrity": "sha512-+gGtJjT6SSHD2l2yC3MCubW/sCV40tZuSs5opdtn79vFSGUgp/lH139RNEQ6Jy078/L0aV8odCw8RSrUcMfLaQ=="
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -1461,6 +1501,15 @@
"zrender": "5.4.4"
}
},
"echarts-gl": {
"version": "2.0.9",
"resolved": "https://registry.npmmirror.com/echarts-gl/-/echarts-gl-2.0.9.tgz",
"integrity": "sha512-oKeMdkkkpJGWOzjgZUsF41DOh6cMsyrGGXimbjK2l6Xeq/dBQu4ShG2w2Dzrs/1bD27b2pLTGSaUzouY191gzA==",
"requires": {
"claygl": "^1.2.1",
"zrender": "^5.1.1"
}
},
"esbuild": {
"version": "0.19.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz",
@ -1637,6 +1686,11 @@
"source-map": "^0.7.3"
}
},
"throttle-debounce": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.0.tgz",
"integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg=="
},
"tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
@ -1666,6 +1720,14 @@
"@vue/shared": "3.3.8"
}
},
"vue3-seamless-scroll": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/vue3-seamless-scroll/-/vue3-seamless-scroll-2.0.1.tgz",
"integrity": "sha512-mI3BaDU3pjcPUhVSw3/xNKdfPBDABTi/OdZaZqKysx4cSdNfGRbVvGNDzzptBbJ5S7imv5T55l6x/SqgnxKreg==",
"requires": {
"throttle-debounce": "5.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",

View File

@ -10,8 +10,10 @@
},
"dependencies": {
"echarts": "^5.4.3",
"echarts-gl": "^2.0.9",
"stylus": "^0.61.0",
"vue": "^3.3.8"
"vue": "^3.3.8",
"vue3-seamless-scroll": "^2.0.1"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.5.0",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

@ -12,35 +12,11 @@
<ModuleCenter class="center"/>
<ModuleBottom class="bottom"/>
<!-- <CardTwoCount/>
<PersonCount2 :bg-type="2"/>
<PersonCount2/>
<PersonCount1/>
<CardCount2/>
<CardCount1 bg="assets/imgs/card/bg2.png"/>
<Process/>
<CircleWave/>
<Bar id="bar" w="300" h="250" :x-data="barChart.xData" :data="barChart.data" />
<BarSpike id="barSpike" w="300" h="250" :x-data="barChart.xData" :data="barChart.data" />
<PolarHalf id="polarHalf" w="600" :data="polarHalfChart.data" :unit="polarHalfChart.unit" /> -->
</div>
</div>
</template>
<script setup>
import { reactive } from 'vue';
import Bar from './components/echarts/Bar.vue';
import PolarHalf from './components/echarts/PolarHalf.vue';
import CircleWave from './components/circle/CircleWave.vue';
import Process from './components/process/Process.vue';
import CardCount1 from './components/card/CardCount1.vue';
import CardCount2 from './components/card/CardCount2.vue';
import PersonPercent from './components/card/PersonPercent.vue';
import PersonCount1 from './components/card/PersonCount1.vue';
import PersonCount2 from './components/card/PersonCount2.vue';
import CardTwoCount from './components/card/CardTwoCount.vue';
import ModuleLeft1 from './module/ModuleLeft1.vue';
import ModuleLeft2 from './module/ModuleLeft2.vue';
import ModuleLeft3 from './module/ModuleLeft3.vue';
@ -61,10 +37,16 @@ import ModuleBottom from './module/ModuleBottom.vue';
background-image url('assets/imgs/bg.png')
background-size 100% 120%
background-position center
.main-title
height 100px
background-image url(assets/imgs/title-bg.png)
background-size 100% 100%
.main-body
margin-top -25px
padding 0 45px 20px 45px
display grid
grid-template-columns 400px 1fr 400px
grid-gap 5px
grid-gap 30px
grid-auto-rows auto
.left1
grid-column 1

View File

@ -45,14 +45,14 @@ if(props.type === 2) {
display flex
flex-direction column
justify-content space-between
width 150px
height 55px
padding 5px 30px
width 140px
height 45px
padding 5px 20px
background-repeat no-repeat
background-size 100% 100%
color #FFFFFF
.top
font-size 18px
font-size 14px
font-weight bold
.bottom
display flex
@ -60,7 +60,7 @@ if(props.type === 2) {
align-items center
height 30px
.left
font-size 22px
font-size 18px
.right
font-size 14px
font-size 12px
</style>

View File

@ -1,5 +1,5 @@
<template>
<div class="container">
<div class="bar">
<div :id="domId" :style="{ width: w, height: h }"></div>
</div>
</template>

View File

@ -1,5 +1,5 @@
<template>
<div class="container">
<div class="bar-spike">
<div :id="domId" :style="{ width: w, height: h }"></div>
</div>
</template>

View File

@ -0,0 +1,299 @@
<template>
<div class="pie-3d">
<div :id="domId" :style="{ width: w, height: h }"></div>
</div>
</template>
<script setup>
import { ref, reactive, inject } from 'vue';
import { onMounted } from 'vue';
import 'echarts-gl';
const props = defineProps({
id: String,
w: {
type: Number,
default: 200
},
h: {
type: Number,
default: 200
},
title: {
type: String,
default: '柱状图'
},
xData: {
type: Array,
default: []
},
data: {
type: Array,
default: []
}
});
const echarts = inject('echarts');
const domId = ref(props.id);
const w = ref(`${props.w}px`);
const h = ref(`${props.h}px`);
const getParametricEquation = (startRatio, endRatio) => {
let midRatio = (startRatio + endRatio) / 2;
let startRadian = startRatio * Math.PI * 2;
let endRadian = endRatio * Math.PI * 2;
let midRadian = midRatio * Math.PI * 2;
let offsetX = 0;
let offsetY = 0;
let offsetZ = 0;
let tmp;
return {
u: {
min: 0,
max: Math.PI * 2,
step: Math.PI / 250,
},
v: {
min: 0,
max: Math.PI,
step: Math.PI / 50,
},
x: function (u, v) {
if (midRatio < 0.5) {
if (u < startRadian || u > midRadian + Math.PI) {
tmp =
u - Math.PI - midRadian < 0
? u + Math.PI - midRadian
: u - Math.PI - midRadian;
return (
offsetX +
(Math.sin(startRadian) * tmp) /
(Math.PI - midRadian + startRadian)
);
}
if (u > endRadian && u < midRadian + Math.PI) {
tmp = midRadian + Math.PI - u;
return (
offsetX +
(Math.sin(endRadian) * tmp) /
(Math.PI - midRadian + startRadian)
);
}
} else {
if (u < startRadian && u > midRadian - Math.PI) {
tmp = u + Math.PI - midRadian;
return (
offsetX +
(Math.sin(startRadian) * tmp) /
(Math.PI - midRadian + startRadian)
);
}
if (u > endRadian || u < midRadian - Math.PI) {
tmp =
midRadian - Math.PI - u < 0
? midRadian + Math.PI - u
: midRadian - Math.PI - u;
return (
offsetX +
(Math.sin(endRadian) * tmp) /
(Math.PI - midRadian + startRadian)
);
}
}
return offsetX + Math.sin(v) * Math.sin(u);
},
y: function (u, v) {
if (midRatio < 0.5) {
if (u < startRadian || u > midRadian + Math.PI) {
tmp =
u - Math.PI - midRadian < 0
? u + Math.PI - midRadian
: u - Math.PI - midRadian;
return (
offsetX +
(Math.cos(startRadian) * tmp) /
(Math.PI - midRadian + startRadian)
);
}
if (u > endRadian && u < midRadian + Math.PI) {
tmp = midRadian + Math.PI - u;
return (
offsetX +
(Math.cos(endRadian) * tmp) /
(Math.PI - midRadian + startRadian)
);
}
} else {
if (u < startRadian && u > midRadian - Math.PI) {
tmp = u + Math.PI - midRadian;
return (
offsetX +
(Math.cos(startRadian) * tmp) /
(Math.PI - midRadian + startRadian)
);
}
if (u > endRadian || u < midRadian - Math.PI) {
tmp =
midRadian - Math.PI - u < 0
? midRadian + Math.PI - u
: midRadian - Math.PI - u;
return (
offsetX +
(Math.cos(endRadian) * tmp) /
(Math.PI - midRadian + startRadian)
);
}
}
return offsetX + Math.sin(v) * Math.cos(u);
},
z: function (u, v) {
return offsetZ + (Math.cos(v) > 0 ? 0.1 : -0.1);
},
};
}
// 3D
const getPie3D = (pieData) => {
let series = [];
let sumValue = 0;
let startValue = 0;
let endValue = 0;
let legendData = [];
for (let i = 0; i < pieData.length; i++) {
sumValue += pieData[i].value;
let seriesItem = {
name: !pieData[i].name ? `series${i}` : pieData[i].name,
type: "surface",
parametric: true,
wireframe: {
show: false,
},
pieData: pieData[i],
pieStatus: {
selected: false,
hovered: false,
},
};
if (pieData[i].itemStyle) {
let itemStyle = {};
if (pieData[i].itemStyle.color) {
itemStyle.color = pieData[i].itemStyle.color;
}
if (pieData[i].itemStyle.opacity) {
itemStyle.opacity = pieData[i].itemStyle.opacity;
}
seriesItem.itemStyle = itemStyle;
}
series.push(seriesItem);
}
for (let i = 0; i < series.length; i++) {
endValue = startValue + series[i].pieData.value;
series[i].pieData.startRatio = startValue / sumValue;
series[i].pieData.endRatio = endValue / sumValue;
series[i].parametricEquation = getParametricEquation(series[i].pieData.startRatio, series[i].pieData.endRatio);
startValue = endValue;
legendData.push(series[i].name);
}
let option = {
legend: {
show: true,
type: 'scroll',
orient: 'vertical',
right: 60,
top: 20,
bottom: 20,
textStyle: {
color: '#FFF'
},
data: legendData,
},
tooltip: {
formatter: (params) => {
if (params.seriesName !== "mouseoutSeries") {
return `${params.seriesName}<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color};"></span>${option.series[params.seriesIndex].pieData.value}`;
}
},
},
xAxis3D: {
min: -0.6,
max: 0.6,
},
yAxis3D: {
min: -0.6,
max: 0.6,
},
zAxis3D: {
min: -0.6,
max: 0.6,
},
grid3D: {
show: false,
boxHeight: 100, //
top: 0,
left: -80,
viewControl: {
//3d
alpha: 40, //
beta: 180, //
rotateSensitivity: 0,
zoomSensitivity: 0,
panSensitivity: 0,
autoRotate: false,
},
light: {
main: {
color: "rgb(85, 84, 84)", //
shadow: false, //
alpha: 80, // x
},
},
},
series: series,
};
return option;
}
const dataSource = [
{
name: "啤酒",
value: 15,
},
{
name: "高粱酒",
value: 33,
},
{
name: "桃花酿",
value: 66,
},
{
name: "白酒",
value: 13,
},
];
const init = () => {
// const colorList = ["#D98053", "#E2B062", "#5A9CF1", "#6ED3D3"];
const colorList = [];
const paramsList = dataSource.map((item, index) => {
return {
...item,
shading: "realistic",
itemStyle: {
color: colorList[index],
},
};
});
let option = getPie3D(paramsList);
var chart = echarts.init(document.getElementById(domId.value));
chart.setOption(option)
}
onMounted(() => {
init();
});
</script>
<style lang="stylus" scoped>
</style>

View File

@ -0,0 +1,110 @@
<template>
<div class="scroll-panel">
<div class="title">
<span class="item item1">序号</span>
<span class="item item2">民族</span>
<span class="item item3">人数()</span>
<span class="item item4">占有率(%)</span>
</div>
<div class="scroll">
<vue3-seamless-scroll :list="listData" :step="0.5">
<div class="line" v-for="item in listData" :key="item">
<span class="item item1">序号</span>
<span class="item item2">民族民族民族民族民族</span>
<span class="item item3">人数()</span>
<span class="item item4">占有率(%)</span>
</div>
</vue3-seamless-scroll>
</div>
</div>
</template>
<script setup>
import { reactive } from 'vue';
import { Vue3SeamlessScroll } from "vue3-seamless-scroll";
const listData = reactive([{
title: "无缝滚动第一行无缝滚动第一行",
date: "2017-12-16",
},
{
title: "无缝滚动第二行无缝滚动第二行",
date: "2017-12-16",
},
{
title: "无缝滚动第三行无缝滚动第三行",
date: "2017-12-16",
},
{
title: "无缝滚动第四行无缝滚动第四行",
date: "2017-12-16",
},
{
title: "无缝滚动第五行无缝滚动第五行",
date: "2017-12-16",
},
{
title: "无缝滚动第六行无缝滚动第六行",
date: "2017-12-16",
},
{
title: "无缝滚动第七行无缝滚动第七行",
date: "2017-12-16",
},
{
title: "无缝滚动第八行无缝滚动第八行",
date: "2017-12-16",
},
{
title: "无缝滚动第九行无缝滚动第九行",
date: "2017-12-16",
}])
</script>
<style lang="stylus" scoped>
.scroll-panel
width 400px
height 200px
font-size 14px
.title
.item
display inline-block
text-align center
.item1
width 60px
.item2
width 140px
.item3
width 100px
.item4
width 100px
.scroll
height 180px
overflow hidden
.line
height 30px
line-height 30px
padding 5px 0
.item
display inline-block
text-align center
overflow hidden
text-overflow ellipsis
white-space nowrap
.item1
width 60px
.item2
width 140px
.item3
width 100px
.item4
width 100px
&:nth-child(n)
background-color rgba(4, 30, 65, 1)
&:nth-child(2n)
background-color rgba(4, 30, 65, 0.5)
</style>

View File

@ -34,7 +34,7 @@ import CircleWave from '../components/circle/CircleWave.vue';
display flex
background-image url(assets/imgs/card/bg9.png)
.left
width 350px
width 550px
height 200px
position relative
.circle-container

View File

@ -1,12 +1,15 @@
1<template>
<div class="module-center">
<CardCount1 id="xtlCount" :type="1" title="稀土路街道" unit="人"/>
<CardCount1 id="mxlCount" :type="3" title="民馨路街道" unit="人"/>
<CardCount1 id="wsqCount" :type="4" title="万水泉镇" unit="人"/>
<CardCount1 id="totalCount" :type="2" title="总人口数" unit="人"/>
<CardCount1 id="xtlCount" class="item" :type="1" title="稀土路街道" unit="人"/>
<CardCount1 id="mxlCount" class="item" :type="3" title="民馨路街道" unit="人"/>
<CardCount1 id="wsqCount" class="item" :type="4" title="万水泉镇" unit="人"/>
<CardCount1 id="totalCount" class="item" :type="2" title="总人口数" unit="人"/>
<PersonPercent id="manPercent" class="item"/>
<PersonPercent id="womenPercent" class="item" type="women"/>
<CardTwoCount id="cardTwoCount" class="item"/>
<img id="xtlIcon" class="stree-icon" src="assets/imgs/icon/xtl.png">
<img id="mxlIcon" class="stree-icon" src="assets/imgs/icon/mxl.png">
<img id="wsqIcon" class="stree-icon" src="assets/imgs/icon/wsq.png">
</div>
</template>
@ -20,7 +23,6 @@ import CardTwoCount from '../components/card/CardTwoCount.vue';
.module-center
width 800px
height 600px
border 1px solid #ccc
background-image url(assets/imgs/center-map-bg.png)
background-size 100% 400px
background-repeat no-repeat
@ -29,6 +31,32 @@ import CardTwoCount from '../components/card/CardTwoCount.vue';
position absolute
top 0
left 0
.stree-icon
position absolute
top 0
left 0
width 25px
#totalCount
top 280px
left 300px
#xtlIcon
top 30px
left 300px
#xtlCount
top 20px
left 330px
#mxlIcon
top 140px
left 60px
#mxlCount
top 180px
left 10px
#wsqIcon
top 220px
left 560px
#wsqCount
top 220px
left 600px
#manPercent
top 400px
left 210px
@ -40,4 +68,5 @@ import CardTwoCount from '../components/card/CardTwoCount.vue';
top 400px
left 320px
transform scale(0.8)
</style>

View File

@ -20,5 +20,7 @@ const barChart = reactive({
</script>
<style lang="stylus" scoped>
.module
.bar-spike
background-image url(assets/imgs/card/bg9.png)
</style>

View File

@ -1,6 +1,7 @@
<template>
<div class="module">
<ModuleCard1 title="宗教信仰统计">
<ScrollPanel/>
</ModuleCard1>
</div>
</template>
@ -8,6 +9,7 @@
<script setup>
import { reactive } from 'vue';
import ModuleCard1 from './card/ModuleCard1.vue';
import ScrollPanel from '../components/scroll/ScrollPanel.vue';
</script>

View File

@ -19,5 +19,7 @@ const barChart = reactive({
</script>
<style lang="stylus" scoped>
.module
.bar
background-image url(assets/imgs/card/bg9.png)
</style>

View File

@ -1,6 +1,7 @@
<template>
<div class="module">
<ModuleCard2 title="政治面貌统计">
<Pie3d id="pie3d" w="400" h="200" />
</ModuleCard2>
</div>
</template>
@ -8,9 +9,12 @@
<script setup>
import { reactive } from 'vue';
import ModuleCard2 from './card/ModuleCard2.vue';
import Pie3d from '../components/echarts/Pie3d.vue';
</script>
<style lang="stylus" scoped>
.module
.pie-3d
background-image url(assets/imgs/card/bg9.png)
</style>

View File

@ -15,7 +15,7 @@ import { ref, defineProps } from 'vue'
const props = defineProps({
w: {
type: Number,
default: 600
default: 800
},
title: {
type: String,
@ -23,10 +23,10 @@ const props = defineProps({
}
})
const width = ref(`${props.w}px`);
const height = ref(`${props.w / 2}px`);
const titleH = ref(`${props.w / 6}px`);
const bodyT = ref(`${props.w / 8}px`)
const bodyH = ref(`${props.w / 3}px`);
const height = ref(`300px`);
const titleH = ref(`${props.w / 8}px`);
const bodyT = ref(`${props.w / 10}px`)
const bodyH = ref(`${props.w / 4}px`);
</script>
<style lang="stylus" scoped>