feat:input
BIN
src/assets/images/inputs/1.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
src/assets/images/inputs/2.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
src/assets/images/inputs/3.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
src/assets/images/inputs/4.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
src/assets/images/inputs/5.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
src/assets/images/inputs/6.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
src/assets/images/inputs/bg_label.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
src/assets/images/inputs/bg_title.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
src/assets/images/inputs/bg_value.png
Normal file
After Width: | Height: | Size: 38 KiB |
@ -1,131 +0,0 @@
|
||||
<template>
|
||||
<div class="cases-alerts-warp">
|
||||
<div class="cases-alerts" :style="{ 'background-image': 'url(' + getAssetsFile('images/inputs/partbg1.png') + ')' }">
|
||||
<div class="cases-alerts-content">
|
||||
<div class="cases-alerts-item-pos">
|
||||
<template v-for="(n, index) in datalist" :key="index">
|
||||
<div class="cases-alerts-item">
|
||||
<div class="header" :style="{ 'background-image': 'url(' + getAssetsFile('images/inputs/partbg2.png') + ')' }">
|
||||
<div class="title">{{ n.title }}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<template v-for="(m, mindex) in n.valStr" :key="mindex">
|
||||
<div class="content-item" :style="{ 'background-image': 'url(' + getAssetsFile('images/inputs/partbg3.png') + ')' }">
|
||||
<div class="num">{{ m }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { isEmpty, getAssetsFile } from '@/utils';
|
||||
const datalist = reactive([
|
||||
{ title: '案件次数', val: 100 },
|
||||
{ title: '预警次数', val: 236 },
|
||||
]);
|
||||
|
||||
onMounted(() => {
|
||||
if (datalist.length && datalist.length > 0) {
|
||||
datalist.forEach((m) => {
|
||||
let valStr = '';
|
||||
|
||||
if (m.val < 1000 && m.val >= 100) {
|
||||
valStr = '0' + m.val;
|
||||
} else if (m.val < 100 && m.val >= 10) {
|
||||
valStr = '00' + m.val;
|
||||
} else if (m.val < 10) {
|
||||
valStr = '000' + m.val;
|
||||
} else {
|
||||
valStr = m.val.toFixed(0);
|
||||
}
|
||||
m.valStr = [...valStr];
|
||||
// console.info('valStr', m.valStr);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
div {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.cases-alerts-warp {
|
||||
height: 100%;
|
||||
padding: 8px;
|
||||
.cases-alerts {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
.cases-alerts-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 20px;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
.cases-alerts-item-pos {
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.cases-alerts-item {
|
||||
display: inline-block;
|
||||
width: calc((100% - 20px) / 2);
|
||||
.header,
|
||||
.content {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
}
|
||||
.header {
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
line-height: 32px;
|
||||
height: 32px;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
transform: skewX(-8deg);
|
||||
background: linear-gradient(to bottom, '#ff7e5f', '#548fff');
|
||||
-webkit-background-clip: text;
|
||||
color: #fff;
|
||||
letter-spacing: 8px;
|
||||
text-shadow: -6px 0 0 1px #add8f1;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
justify-content: space-around;
|
||||
margin-top: 30%;
|
||||
.content-item {
|
||||
height: 36px;
|
||||
display: inline-block;
|
||||
width: calc((100% - 20px) / 4);
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
line-height: 36px;
|
||||
text-align: center;
|
||||
.num {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
transform: skewX(-8deg);
|
||||
background: linear-gradient(to bottom, '#ff7e5f', '#548fff');
|
||||
-webkit-background-clip: text;
|
||||
color: #fff;
|
||||
text-shadow: -6px 0 0 1px #add8f1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
275
src/views/inputs/components/inputsFour.vue
Normal file
@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<custom-echart-pie-3d :chart-data="state.data" height="100%" :option="state.option" />
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
|
||||
const state = reactive({
|
||||
option: {},
|
||||
data: [],
|
||||
});
|
||||
|
||||
const pieData = [
|
||||
{ value: 530, name: '种源企业', itemStyle: { color: '#8fd7fce8' } },
|
||||
{ value: 1215, name: '肥料厂家', itemStyle: { color: '#466BE7e8' } },
|
||||
{ value: 2312, name: '农药厂家', itemStyle: { color: '#F4BB29e8' } },
|
||||
{ value: 916, name: '其他', itemStyle: { color: '#FF8329' } },
|
||||
];
|
||||
|
||||
// 生成扇形的曲面参数方程,用于 series-surface.parametricEquation
|
||||
function getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
|
||||
// 计算
|
||||
let midRatio = (startRatio + endRatio) / 2;
|
||||
let startRadian = startRatio * Math.PI * 2;
|
||||
let endRadian = endRatio * Math.PI * 2;
|
||||
let midRadian = midRatio * Math.PI * 2;
|
||||
// 如果只有一个扇形,则不实现选中效果。
|
||||
if (startRatio === 0 && endRatio === 1) {
|
||||
isSelected = false;
|
||||
}
|
||||
// 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
|
||||
k = typeof k !== 'undefined' ? k : 1 / 3;
|
||||
// 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
|
||||
let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
|
||||
let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
|
||||
// 计算高亮效果的放大比例(未高亮,则比例为 1)
|
||||
let hoverRate = isHovered ? 1.05 : 1;
|
||||
// 返回曲面参数方程
|
||||
return {
|
||||
u: {
|
||||
min: -Math.PI,
|
||||
max: Math.PI * 3,
|
||||
step: Math.PI / 32,
|
||||
},
|
||||
v: {
|
||||
min: 0,
|
||||
max: Math.PI * 2,
|
||||
step: Math.PI / 20,
|
||||
},
|
||||
x: function (u, v) {
|
||||
if (u < startRadian) {
|
||||
return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
}
|
||||
if (u > endRadian) {
|
||||
return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
}
|
||||
return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
},
|
||||
y: function (u, v) {
|
||||
if (u < startRadian) {
|
||||
return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
}
|
||||
if (u > endRadian) {
|
||||
return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
}
|
||||
return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
},
|
||||
z: function (u, v) {
|
||||
if (u < -Math.PI * 0.5) {
|
||||
return Math.sin(u);
|
||||
}
|
||||
if (u > Math.PI * 2.5) {
|
||||
return Math.sin(u) * h * 0.1;
|
||||
}
|
||||
return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function fomatFloat(num, n) {
|
||||
var f = parseFloat(num);
|
||||
if (isNaN(f)) {
|
||||
return false;
|
||||
}
|
||||
f = Math.round(num * Math.pow(10, n)) / Math.pow(10, n); // n 幂
|
||||
var s = f.toString();
|
||||
var rs = s.indexOf('.');
|
||||
if (rs < 0) {
|
||||
rs = s.length;
|
||||
s += '.';
|
||||
}
|
||||
while (s.length <= rs + n) {
|
||||
s += '0';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
// 获取3d丙图的最高扇区的高度
|
||||
function getHeight3D(series, height) {
|
||||
series.sort((a, b) => {
|
||||
return b.pieData.value - a.pieData.value;
|
||||
});
|
||||
return (height * 20) / series[0].pieData.value;
|
||||
}
|
||||
|
||||
// 获取配置项
|
||||
function getPie3D(pieData, internalDiameterRatio) {
|
||||
let series = [];
|
||||
let sumValue = 0;
|
||||
let startValue = 0;
|
||||
let endValue = 0;
|
||||
let legendData = [];
|
||||
let legendBfb = [];
|
||||
let k = 1 - internalDiameterRatio;
|
||||
pieData.sort((a, b) => {
|
||||
return b.value - a.value;
|
||||
});
|
||||
for (let i = 0; i < pieData.length; i++) {
|
||||
sumValue += pieData[i].value;
|
||||
let seriesItem = {
|
||||
//名称
|
||||
name: typeof pieData[i].name === 'undefined' ? `series${i}` : pieData[i].name,
|
||||
type: 'surface',
|
||||
//是否为参数曲面(是)
|
||||
parametric: true,
|
||||
//曲面图网格线(否)上面一根一根的
|
||||
wireframe: {
|
||||
show: false,
|
||||
},
|
||||
pieData: pieData[i],
|
||||
pieStatus: {
|
||||
selected: false,
|
||||
hovered: false,
|
||||
k: k,
|
||||
},
|
||||
|
||||
//设置饼图在容器中的位置(目前没发现啥用)
|
||||
// center: ['50%', '100%']
|
||||
};
|
||||
|
||||
//曲面的颜色、不透明度等样式。
|
||||
if (typeof pieData[i].itemStyle != 'undefined') {
|
||||
let itemStyle = {};
|
||||
typeof pieData[i].itemStyle.color != 'undefined' ? (itemStyle.color = pieData[i].itemStyle.color) : null;
|
||||
typeof pieData[i].itemStyle.opacity != 'undefined' ? (itemStyle.opacity = pieData[i].itemStyle.opacity) : null;
|
||||
seriesItem.itemStyle = itemStyle;
|
||||
}
|
||||
series.push(seriesItem);
|
||||
}
|
||||
|
||||
legendData = [];
|
||||
legendBfb = [];
|
||||
for (let i = 0; i < series.length; i++) {
|
||||
endValue = startValue + series[i].pieData.value * 1;
|
||||
series[i].pieData.startRatio = startValue / sumValue;
|
||||
series[i].pieData.endRatio = endValue / sumValue;
|
||||
series[i].parametricEquation = getParametricEquation(
|
||||
series[i].pieData.startRatio,
|
||||
series[i].pieData.endRatio,
|
||||
false,
|
||||
false,
|
||||
k,
|
||||
series[i].pieData.value
|
||||
);
|
||||
startValue = endValue;
|
||||
let bfb = fomatFloat(series[i].pieData.value / sumValue, 4);
|
||||
legendData.push({
|
||||
name: series[i].name,
|
||||
value: bfb,
|
||||
});
|
||||
legendBfb.push({
|
||||
name: series[i].name,
|
||||
value: bfb,
|
||||
});
|
||||
}
|
||||
|
||||
let boxHeight = getHeight3D(series, 15);
|
||||
let option = {
|
||||
legend: {
|
||||
data: legendData,
|
||||
color: ['#8FD7FC', '#466BE7', '#F4BB29', '#49C384', '#8FD7FC', '#466BE7', '#F4BB29', '#49C384'],
|
||||
bottom: 20,
|
||||
itemGap: 20,
|
||||
show: true,
|
||||
icon: 'rect',
|
||||
itemHeight: 10,
|
||||
itemWidth: 10,
|
||||
textStyle: {
|
||||
fontSize: 12,
|
||||
color: '#B8DDFF',
|
||||
lineHeight: 20,
|
||||
},
|
||||
// formatter: function (name) {
|
||||
// var target;
|
||||
// for (var i = 0, l = pieData.length; i < l; i++) {
|
||||
// if (pieData[i].name == name) {
|
||||
// target = pieData[i].value;
|
||||
// }
|
||||
// }
|
||||
// return `${name} ${target}`;
|
||||
// },
|
||||
},
|
||||
title: {
|
||||
text: `{a|45%}{c|\n肥料厂家}`,
|
||||
x: 'center',
|
||||
y: 'center',
|
||||
textStyle: {
|
||||
rich: {
|
||||
a: {
|
||||
fontSize: 20,
|
||||
color: '#fff',
|
||||
},
|
||||
c: {
|
||||
fontSize: 12,
|
||||
color: '#fff',
|
||||
padding: [15, 0],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
show: false,
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||
borderColor: 'transparent',
|
||||
formatter: (params) => {
|
||||
if (params.seriesName !== 'mouseoutSeries' && params.seriesName !== 'pie2d') {
|
||||
let bfb = ((option.series[params.seriesIndex].pieData.endRatio - option.series[params.seriesIndex].pieData.startRatio) * 100).toFixed(2);
|
||||
const value = option.series[params.seriesIndex].pieData.value;
|
||||
return (
|
||||
`<div style='color:rgba(214, 243, 255, 0.9);'>` +
|
||||
`<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color};"></span>` +
|
||||
`${params.seriesName}<br/>` +
|
||||
`<span style='margin-right:20px'>${value}</span>` +
|
||||
`<span >${bfb}%</span>` +
|
||||
`</div>`
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
xAxis3D: {
|
||||
min: -1,
|
||||
max: 1,
|
||||
},
|
||||
yAxis3D: {
|
||||
min: -1,
|
||||
max: 1,
|
||||
},
|
||||
zAxis3D: {
|
||||
min: -1,
|
||||
max: 1,
|
||||
},
|
||||
grid3D: {
|
||||
show: false,
|
||||
boxHeight: boxHeight,
|
||||
left: 0,
|
||||
top: -10,
|
||||
viewControl: {
|
||||
alpha: 45, //角度(这个很重要 调节角度的)
|
||||
distance: 180, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||
rotateSensitivity: 1, //设置为0无法旋转
|
||||
zoomSensitivity: 1, //设置为0无法缩放
|
||||
panSensitivity: 0, //设置为0无法平移
|
||||
autoRotate: true, //自动旋转
|
||||
},
|
||||
},
|
||||
series: series,
|
||||
};
|
||||
return option;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const option = getPie3D(pieData, 0.8);
|
||||
state.option = option;
|
||||
state.data = option.series;
|
||||
});
|
||||
</script>
|
@ -1,74 +0,0 @@
|
||||
<template>
|
||||
<div class="inputs-gmp-charts">
|
||||
<custom-echart-pie :chart-data="chartsData.valData" height="100%" :option="chartsData.option" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
|
||||
const chartsData = reactive({
|
||||
option: {
|
||||
color: ['#3685fe', '#41b879', '#ffd500'],
|
||||
title: {
|
||||
text: ' ',
|
||||
textStyle: {
|
||||
color: '#333',
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: ['耿马镇', '勐撒镇', '勐永镇', '孟定镇', '勐简乡', '贺派乡', '四排山乡', '芒洪乡', '大兴乡'],
|
||||
right: '0', // 距离左侧10%的位置
|
||||
top: 'middle', // 垂直居中
|
||||
orient: 'vertical', // 图例垂直排列
|
||||
itemWidth: 15, // 图例标记的宽度
|
||||
itemHeight: 8, // 图例标记的高度
|
||||
textStyle: {
|
||||
fontSize: 10, // 图例文字的字体大小
|
||||
color: '#fff', // 图例文字的颜色
|
||||
},
|
||||
},
|
||||
label: {
|
||||
color: '#333',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: [20, 80],
|
||||
roseType: 'area',
|
||||
center: ['40%', '50%'],
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
itemStyle: {
|
||||
borderRadius: 5,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
valData: [
|
||||
{ value: 205, name: '耿马镇' },
|
||||
{ value: 308, name: '勐撒镇' },
|
||||
{ value: 359, name: '勐永镇' },
|
||||
{ value: 452, name: '孟定镇' },
|
||||
{ value: 388, name: '勐简乡' },
|
||||
{ value: 508, name: '贺派乡' },
|
||||
{ value: 369, name: '四排山乡' },
|
||||
{ value: 610, name: '芒洪乡' },
|
||||
{ value: 754, name: '大兴乡' },
|
||||
],
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (chartsData.valData && chartsData.valData.length) {
|
||||
chartsData.valData.forEach((m, index) => {
|
||||
let num = 100;
|
||||
m.value = (Number(m.value) + Math.random() + num).toFixed(2);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.inputs-gmp-charts {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
@ -18,9 +18,8 @@
|
||||
</centerMap>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue';
|
||||
import centerMap from '@/components/centerMap.vue';
|
||||
|
||||
const unit = ref('家');
|
||||
const list = reactive([
|
||||
@ -32,9 +31,9 @@ const list = reactive([
|
||||
{ title: '投入品规模', value: '3000', color: '#FC0003', unit: '万元' },
|
||||
]);
|
||||
|
||||
let currentRegion = reactive(null);
|
||||
let currentRegion = ref(null);
|
||||
const doMapclick = (data) => {
|
||||
currentRegion = data;
|
||||
currentRegion.value = data;
|
||||
};
|
||||
</script>
|
||||
|
||||
|
89
src/views/inputs/components/inputsOne.vue
Normal file
@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col v-for="item in state.list" :key="item.label" :span="12">
|
||||
<div class="inputs-item flex-row">
|
||||
<span class="inputs-item-icon">
|
||||
<img :src="item.icon" />
|
||||
</span>
|
||||
<div class="inputs-item-info flex-column">
|
||||
<b>{{ item.label }}</b>
|
||||
<div class="inputs-item-value flex-row">
|
||||
<em>{{ item.value }}</em>
|
||||
<span>{{ item.unit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive } from 'vue';
|
||||
import { getAssetsFile } from '@/utils';
|
||||
|
||||
const state = reactive({
|
||||
list: [
|
||||
{
|
||||
label: '监管机构',
|
||||
value: 88,
|
||||
unit: '家',
|
||||
icon: getAssetsFile('images/inputs/1.png'),
|
||||
},
|
||||
{
|
||||
label: '监管人员',
|
||||
value: 106,
|
||||
unit: '人',
|
||||
icon: getAssetsFile('images/inputs/2.png'),
|
||||
},
|
||||
{
|
||||
label: '村级监管员',
|
||||
value: 38,
|
||||
unit: '人',
|
||||
icon: getAssetsFile('images/inputs/3.png'),
|
||||
},
|
||||
{
|
||||
label: '农资经营单位',
|
||||
value: 27,
|
||||
unit: '家',
|
||||
icon: getAssetsFile('images/inputs/4.png'),
|
||||
},
|
||||
{
|
||||
label: '生产主体',
|
||||
value: 154,
|
||||
unit: '家',
|
||||
icon: getAssetsFile('images/inputs/5.png'),
|
||||
},
|
||||
{
|
||||
label: '检测机构',
|
||||
value: 16,
|
||||
unit: '家',
|
||||
icon: getAssetsFile('images/inputs/6.png'),
|
||||
},
|
||||
],
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.inputs {
|
||||
&-item {
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
padding: 10px 0;
|
||||
|
||||
&-icon {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
&-info {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&-value {
|
||||
margin-top: 10px;
|
||||
justify-content: space-between;
|
||||
em {
|
||||
color: #02fd94;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
77
src/views/inputs/components/inputsThere.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<custom-echart-bar :chart-data="state.data" height="100%" :option="state.option" />
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive } from 'vue';
|
||||
|
||||
const state = reactive({
|
||||
option: {
|
||||
grid: {
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '5%',
|
||||
top: '10%',
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
formatter: (data) => {
|
||||
const params = data[0];
|
||||
let str = `<div class="custom-echarts-tips">
|
||||
<span>${params.name}</span><br/>
|
||||
<span>${params.marker} ${params.data} 万元</span>
|
||||
</div>`;
|
||||
return str;
|
||||
},
|
||||
},
|
||||
barStyle: {
|
||||
barWidth: 15,
|
||||
itemStyle: {
|
||||
borderRadius: [8, 8, 0, 0],
|
||||
},
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#35D0C0' },
|
||||
{ offset: 1, color: '#35D0C0' },
|
||||
],
|
||||
global: false,
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
// name: '面积',
|
||||
axisTick: {
|
||||
show: false,
|
||||
alignWithLabel: false,
|
||||
interval: 'auto',
|
||||
inside: false,
|
||||
length: 5,
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
width: 1,
|
||||
color: 'rgba(28, 158, 222, 1)',
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
// name: '面积(万亩)',
|
||||
},
|
||||
},
|
||||
data: [
|
||||
{ value: 530, name: '种子' },
|
||||
{ value: 1215, name: '化肥' },
|
||||
{ value: 2312, name: '农药' },
|
||||
{ value: 916, name: '地膜' },
|
||||
{ value: 108, name: '水' },
|
||||
],
|
||||
});
|
||||
</script>
|
83
src/views/inputs/components/inputsTwo.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<div class="inputs">
|
||||
<h2 class="inputs-title">检测批次:15684次</h2>
|
||||
<el-row>
|
||||
<el-col v-for="item in state.list" :key="item.label" :span="12">
|
||||
<div class="inputs-item flex-column">
|
||||
<div class="inputs-item-value">{{ item.value }}</div>
|
||||
<div class="inputs-item-label">{{ item.label }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive } from 'vue';
|
||||
|
||||
const state = reactive({
|
||||
list: [
|
||||
{
|
||||
label: '检测合格率',
|
||||
value: '98.99%',
|
||||
},
|
||||
{
|
||||
label: '检测覆盖率',
|
||||
value: '99.98%',
|
||||
},
|
||||
],
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.inputs {
|
||||
&-title {
|
||||
width: 240px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
margin: 24px auto 0;
|
||||
background-image: url('@/assets/images/inputs/bg_title.png');
|
||||
background-position: center bottom;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100%;
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
text-shadow:
|
||||
0 0 10px #01eeff,
|
||||
0 0 20px #01eeff,
|
||||
0 0 30px #01eeff,
|
||||
0 0 40px #01eeff;
|
||||
}
|
||||
&-item {
|
||||
&-label {
|
||||
width: 120px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
margin: 0 auto 0;
|
||||
background: url('@/assets/images/inputs/bg_label.png') center center no-repeat;
|
||||
background-size: 100%;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
text-shadow:
|
||||
0 0 10px #01eeff,
|
||||
0 0 20px #01eeff,
|
||||
0 0 30px #01eeff,
|
||||
0 0 40px #01eeff;
|
||||
}
|
||||
|
||||
&-value {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
line-height: 180px;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
background-image: url('@/assets/images/inputs/bg_value.png');
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,154 +0,0 @@
|
||||
<template>
|
||||
<div class="demo roll-list-land-plan" style="height: 100%" ref="refroll">
|
||||
<!-- <div class="list-item-header item-warp" :style="{ flex: listKeys.length }">
|
||||
<template v-for="(h, indexh) in listKeys" :key="indexh">
|
||||
<div class="item-td" :style="{ width: 'calc(100% / ' + listKeys.length + ')' }">{{ listKeysHeader[h] }}</div>
|
||||
</template>
|
||||
</div> -->
|
||||
<vue3ScrollSeamless class="scroll-wrap" :class-options="classOptions" :data-list="datalist">
|
||||
<div v-for="(item, index) in datalist" :key="index" class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-boday item-warp" :style="{ flex: listKeys.length }">
|
||||
<div class="item-content">
|
||||
<div class="label">{{ item.title }}</div>
|
||||
<customProgress height="10px" :percent="item.percent"></customProgress>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</vue3ScrollSeamless>
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, computed, reactive } from 'vue';
|
||||
import { vue3ScrollSeamless } from 'vue3-scroll-seamless';
|
||||
import customProgress from '@/components/customProgress.vue';
|
||||
const props = defineProps({
|
||||
// items: {
|
||||
// type: Array,
|
||||
// default: () => [],
|
||||
// },
|
||||
});
|
||||
|
||||
let list = reactive([
|
||||
{ title: '农药', value: 357 },
|
||||
{ title: '肥料', value: 159 },
|
||||
{ title: '种源', value: 516 },
|
||||
{ title: '兽药', value: 82 },
|
||||
{ title: '农机', value: 45 },
|
||||
]);
|
||||
|
||||
let refroll = ref(null);
|
||||
|
||||
let datalist = computed(() => {
|
||||
let maxwidth = refroll.value && refroll.value.clientWidth;
|
||||
return list.map((m) => {
|
||||
return {
|
||||
...m,
|
||||
percent: Number((Number(parseInt(m.value) / max.value) * 100).toFixed(0)),
|
||||
pwidth: parseInt(Number(parseInt(m.value) / max.value) * maxwidth),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
let max = computed(() => {
|
||||
let valueList = new Set(list.map((item) => item.value));
|
||||
let sortValue = [...valueList].sort((a, b) => b - a) || [];
|
||||
// console.info('valueList', sortValue);
|
||||
return sortValue.length ? sortValue[0] : 0;
|
||||
});
|
||||
|
||||
const listKeys = reactive(['title', 'value']);
|
||||
const listKeysHeader = reactive({
|
||||
title: '分类',
|
||||
value: '数量',
|
||||
});
|
||||
|
||||
const classOptions = {
|
||||
singleHeight: 48,
|
||||
};
|
||||
onMounted(() => {});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.roll-list-land-plan {
|
||||
margin-top: 8px;
|
||||
::v-deep() {
|
||||
.el-progress-bar__outer {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
.scroll-wrap {
|
||||
height: 90%;
|
||||
width: 100%;
|
||||
margin: 4px auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
.list-item-header {
|
||||
background: #144482;
|
||||
font-size: 10px;
|
||||
width: 100%;
|
||||
.item-td {
|
||||
padding: 8px 6px;
|
||||
}
|
||||
}
|
||||
.list-item-boday {
|
||||
background: transparent;
|
||||
width: 100%;
|
||||
.item-td {
|
||||
padding: 4px 6px;
|
||||
&.td-title {
|
||||
color: #6beff9 !important;
|
||||
}
|
||||
&.zebra-b {
|
||||
background: #051225 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.item-warp {
|
||||
display: inline-flex;
|
||||
justify-content: space-around;
|
||||
.item-td {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
}
|
||||
.item-content {
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
justify-content: flex-start;
|
||||
margin: 8px 0;
|
||||
.label,
|
||||
.val {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.label {
|
||||
width: 50px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-item {
|
||||
// border-bottom: 1px dashed rgba(255, 255, 255, 0.2);
|
||||
line-height: 18px;
|
||||
|
||||
.list-item-content {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
justify-content: space-around;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
.demo {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
// margin-top: 10px;
|
||||
}
|
||||
</style>
|
@ -1,119 +0,0 @@
|
||||
<template>
|
||||
<div class="demo roll-list-land-plan" style="height: 90%">
|
||||
<div class="list-item-header item-warp" :style="{ flex: listKeys.length }">
|
||||
<template v-for="(h, indexh) in listKeys" :key="indexh">
|
||||
<div class="item-td" :style="{ width: 'calc(100% / ' + listKeys.length + ')' }">{{ listKeysHeader[h] }}</div>
|
||||
</template>
|
||||
</div>
|
||||
<vue3ScrollSeamless class="scroll-wrap" :class-options="classOptions" :data-list="list">
|
||||
<div v-for="(item, index) in list" :key="index" class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-boday item-warp" :style="{ flex: listKeys.length }">
|
||||
<template v-for="(b, indexb) in listKeys" :key="indexb">
|
||||
<div class="item-td" :class="{ 'zebra-b': (index + 1) % 2 == 0 }" :style="{ width: 'calc(100% / ' + listKeys.length + ')' }">
|
||||
{{ item[b] }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</vue3ScrollSeamless>
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, computed, reactive } from 'vue';
|
||||
import { vue3ScrollSeamless } from 'vue3-scroll-seamless';
|
||||
const props = defineProps({
|
||||
// items: {
|
||||
// type: Array,
|
||||
// default: () => [],
|
||||
// },
|
||||
});
|
||||
|
||||
let list = reactive([
|
||||
{ title: '耿马镇', type: '吡虫啉', time: '2025.01.02', info: '经销商资质不合格' },
|
||||
{ title: '勐撒镇', type: '多菌灵', time: '2025.01.01', info: '农药成分不合格' },
|
||||
{ title: '孟定镇', type: '氯化钾', time: '2025.01.02', info: '经销商资质不合格' },
|
||||
{ title: '孟简镇', type: 'NPK 复合肥', time: '2025.01.01', info: '成分不合格' },
|
||||
{ title: '孟永镇', type: '青霉素', time: '2025.01.02', info: '经销商资质不合格' },
|
||||
{ title: '大兴乡', type: '口蹄疫疫苗', time: '2025.01.01', info: '经销商资质不完全' },
|
||||
{ title: '芒洪乡', type: '大豆种子', time: '2025.01.02', info: '种源质量不好' },
|
||||
{ title: '四排山乡', type: '番茄种子', time: '2025.01.01', info: '经销商资质不合格' },
|
||||
{ title: '贺派乡', type: '草甘膦', time: '2025.01.02', info: '农药成分不合格' },
|
||||
]);
|
||||
|
||||
const listKeys = reactive(['title', 'type', 'time', 'info']);
|
||||
const listKeysHeader = reactive({
|
||||
title: '乡/镇',
|
||||
type: '投入品种类',
|
||||
time: '时间',
|
||||
info: '案件信息',
|
||||
});
|
||||
|
||||
const classOptions = {
|
||||
singleHeight: 48,
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.roll-list-land-plan {
|
||||
margin-top: 8px;
|
||||
.scroll-wrap {
|
||||
height: 80%;
|
||||
width: 100%;
|
||||
margin: 4px auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
.list-item-header {
|
||||
background: #144482;
|
||||
font-size: 10px;
|
||||
width: 100%;
|
||||
.item-td {
|
||||
padding: 8px 6px;
|
||||
}
|
||||
}
|
||||
.list-item-boday {
|
||||
background: transparent;
|
||||
width: 100%;
|
||||
.item-td {
|
||||
padding: 4px 6px;
|
||||
&.td-title {
|
||||
color: #6beff9 !important;
|
||||
}
|
||||
&.zebra-b {
|
||||
background: #051225 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.item-warp {
|
||||
display: inline-flex;
|
||||
justify-content: space-around;
|
||||
.item-td {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.list-item {
|
||||
// border-bottom: 1px dashed rgba(255, 255, 255, 0.2);
|
||||
line-height: 18px;
|
||||
|
||||
.list-item-content {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
justify-content: space-around;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
.demo {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
// margin-top: 10px;
|
||||
}
|
||||
</style>
|
@ -4,47 +4,47 @@
|
||||
<div class="left-charts-item">
|
||||
<customBack top-title="投入品监管体系建设" :top-postion="'left'">
|
||||
<template #back>
|
||||
<inputsType></inputsType>
|
||||
<inputsOne />
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="left-charts-item">
|
||||
<customBack top-title="投入品检测监管" :top-postion="'left'">
|
||||
<template #back>
|
||||
<inputsGmp></inputsGmp>
|
||||
<!-- <inputsTwo /> -->
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="left-charts-item">
|
||||
<customBack top-title="农资监管" :top-postion="'left'">
|
||||
<customBack top-title="投入品金额对比" :top-postion="'left'">
|
||||
<template #back>
|
||||
<landbreedCharts></landbreedCharts>
|
||||
<!-- <inputsThere /> -->
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<inputsMap></inputsMap>
|
||||
<centerMap></centerMap>
|
||||
</el-col>
|
||||
<el-col :span="6" class="right-charts">
|
||||
<div class="right-charts-item">
|
||||
<customBack top-title="生产主体统计" :top-postion="'right'">
|
||||
<template #back>
|
||||
<casesAlerts></casesAlerts>
|
||||
<inputsFour />
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="right-charts-item">
|
||||
<customBack top-title="历年投入品规模对比" :top-postion="'right'">
|
||||
<template #back>
|
||||
<monthlyuseCharts></monthlyuseCharts>
|
||||
<inputsFive />
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="right-charts-item">
|
||||
<customBack top-title="投入品白名单/黑名单" :top-postion="'right'">
|
||||
<template #back>
|
||||
<dealerDistributionCharts></dealerDistributionCharts>
|
||||
<inputsSix />
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
@ -53,12 +53,12 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import centerMap from '@/components/centerMap.vue';
|
||||
import inputsGmp from './components/inputsGmp.vue';
|
||||
import landbreedCharts from './components/landbreedCharts.vue';
|
||||
import monthlyuseCharts from './components/monthlyuseCharts.vue';
|
||||
import dealerDistributionCharts from './components/dealerDistributionCharts.vue';
|
||||
import casesAlerts from './components/casesAlerts.vue';
|
||||
import inputsType from './components/inputsType.vue';
|
||||
import inputsOne from './components/inputsOne.vue';
|
||||
import inputsTwo from './components/inputsTwo.vue';
|
||||
import inputsThere from './components/inputsThere.vue';
|
||||
import inputsFour from './components/inputsFour.vue';
|
||||
import inputsFive from './components/inputsFive.vue';
|
||||
import inputsSix from './components/inputsSix.vue';
|
||||
import inputsMap from './components/inputsMap.vue';
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|