Compare commits

...

2 Commits

Author SHA1 Message Date
lx
7874be1d2e Merge branch 'main' of http://47.109.205.240:3000/Web/digital-agriculture-screen 2025-04-29 09:04:52 +08:00
lx
8680a9b0db feat 2025-04-29 09:04:48 +08:00
8 changed files with 159 additions and 81 deletions

1
components.d.ts vendored
View File

@ -28,6 +28,7 @@ declare module 'vue' {
CustomEchartPieGauge: typeof import('./src/components/custom-echart-pie-gauge/index.vue')['default']
CustomEchartRadar: typeof import('./src/components/custom-echart-radar/index.vue')['default']
CustomEchartScatterBlister: typeof import('./src/components/custom-echart-scatter-blister/index.vue')['default']
CustomEchartTriangle: typeof import('./src/components/custom-echart-triangle/index.vue')['default']
CustomEchartWaterDroplet: typeof import('./src/components/custom-echart-water-droplet/index.vue')['default']
CustomEchartWordCloud: typeof import('./src/components/custom-echart-word-cloud/index.vue')['default']
CustomIframe: typeof import('./src/components/custom-iframe/index.vue')['default']

View File

@ -0,0 +1,125 @@
<template>
<div ref="chartRef" :style="{ height, width }"></div>
</template>
<script>
import { ref, reactive, watch, watchEffect } from 'vue';
import { cloneDeep } from 'lodash';
import { useEcharts } from '@/hooks/useEcharts';
export default {
name: 'CustomEchartTriangle',
props: {
chartData: {
type: Array,
default: () => [],
},
size: {
type: Object,
default: () => {},
},
option: {
type: Object,
default: () => ({}),
},
width: {
type: String,
default: '100%',
},
height: {
type: String,
default: 'calc(100vh - 78px)',
},
},
emits: ['click'],
setup(props, { emit }) {
const chartRef = ref(null);
const { setOptions, getInstance, resize, startAutoPlay } = useEcharts(chartRef);
const option = reactive({
tooltip: {
// trigger: 'axis',
// axisPointer: {
// type: 'shadow',
// },
backgroundColor: 'rgba(18, 55, 85, 0.8);',
borderColor: '#35d0c0',
formatter: (data) => {
const params = data.data;
let str = `<div class="custom-echarts-tips">
<span>${params.name}</span><br/>
<span>${params.reaVal}%</span>
</div>`;
return str;
},
},
series: [
{
zlevel: 1,
name: '漏斗图',
type: 'funnel',
left: 'center',
width: '28%',
sort: 'ascending',
gap: 0,
label: {
show: true,
position: 'right',
width: '200px',
align: 'right',
formatter: function (params) {
let arr = [`{a|${params.data.name}}`, `{b| ${params.data.reaVal}%}`];
return arr.join('\n');
// params.data.name + ':' + params.data.reaVal + '%'};
},
rich: {
a: { color: '#fff', fontSize: '16px' },
b: { color: '#05FCC6', fontSize: '16px' },
},
},
labelLine: {
show: false,
},
itemStyle: {
show: false,
borderColor: '#fff',
borderWidth: 1,
},
emphasis: {
label: {
fontSize: 20,
},
},
data: [],
},
],
});
watchEffect(() => {
props.chartData && initCharts();
});
watch(
() => props.size,
() => {
resize();
},
{
immediate: true,
}
);
function initCharts() {
if (props.option) {
Object.assign(option, cloneDeep(props.option));
}
option.series[0].data = props.chartData;
setOptions(option);
}
function onClick(params) {
emit('click', params);
}
return { chartRef };
},
};
</script>

View File

@ -57,7 +57,7 @@ const props = defineProps({
{ label: '首页', value: 'home' },
{ label: '土地资源', value: 'land' },
{ label: '投入品监管', value: 'inputs' },
{ label: '生产经营主体', value: 'entities' },
{ label: '产出品管理', value: 'entities' },
// { label: '', value: 'plant' },
// { label: '', value: 'breed' },
{ label: '全流程溯源', value: 'trace' },

View File

@ -22,7 +22,7 @@ import customEchartMaps from './custom-echart-maps';
import customScrollTitle from './custom-scroll-title';
import customEchartHyalineCake from './custom-echart-hyaline-cake';
import customEchartColumnLine from './custom-echart-column-line';
import customEchartTriangle from './custom-echart-triangle';
export {
SvgIcon,
CustomIframe,
@ -48,4 +48,5 @@ export {
customScrollTitle,
customEchartHyalineCake,
customEchartColumnLine,
customEchartTriangle,
};

View File

@ -29,7 +29,7 @@ export default {
path: 'entities',
name: 'entities',
component: () => import('@/views/entities/index.vue'),
meta: { title: '生产经营主体', icon: '' },
meta: { title: '产出品管理', icon: '' },
},
// {
// path: 'breed',

View File

@ -29,12 +29,27 @@ const option = reactive({
k: 0.2,
opacity: 0.6,
itemGap: 0,
autoItemHeight: 10,
autoItemHeight: 3,
legend: {
orient: 'horizontal',
bottom: 10,
left: 'center',
},
title: {
text: '23亿元',
textStyle: {
color: '#fff',
fontSize: '26px',
fontWeight: 'bold',
},
subtext: '22.2%',
subtextStyle: {
color: '#07f7c4',
fontSize: '18px',
},
top: 'center',
left: 'center',
},
grid3D: {
show: false,
boxHeight: 5,

View File

@ -44,12 +44,14 @@ const state = reactive({
axisPointer: {
type: 'shadow',
},
backgroundColor: 'rgba(18, 55, 85, 0.8);',
borderColor: '#35d0c0',
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>`;
<span>${params.name}</span><br/>
<span>${params.marker} ${params.data} 万元</span>
</div>`;
return str;
},
},

View File

@ -1,84 +1,18 @@
<template>
<div ref="chartsWarp" class="hot-charts">
<custom-echart-bubble :chart-data="seriesData" height="100%" :option="chartsData.option" />
<custom-echart-triangle :chart-data="data" height="100%" :option="option" />
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
const chartsData = reactive({
option: {},
valData: [
{ name: '多菌灵', value: 6833.37 },
{ name: '复合肥', value: 6823.93 },
{ name: '水溶肥', value: 3529.8 },
{ name: '大豆种子', value: 9773.04 },
{ name: '农膜', value: 2992.33 },
{ name: '草甘膦', value: 1448.23 },
{ name: '其他', value: 3800.77 },
],
});
let chartsWarp = ref(null);
let seriesData = reactive([]);
const compare = (propertyName) => {
return (object1, object2) => {
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if (value2 < value1) {
return 1;
} else if (value2 > value1) {
return -1;
} else {
return 0;
}
};
};
onMounted(() => {
if (chartsData.valData && chartsData.valData.length) {
let datas = chartsData.valData.sort(compare('value')).reverse();
let maxValue = datas[0].value;
let colors = ['#4983F5', '#3D993D', '#525CCC', '#3344FF', '#39ACE5', '#008099', '#2985CC'];
let total = datas.reduce((acc, current) => {
return acc + current.value;
}, 0);
for (var i = 0; i < datas.length; i++) {
let acct = parseFloat((datas[i].value / total).toFixed(2));
if (acct < 0.2) {
acct = 0.2;
}
if (acct > 0.6) {
acct = 0.6;
}
let reference =
chartsWarp.value.clientHeight < chartsWarp.value.clientWidth
? parseInt(chartsWarp.value.clientHeight)
: parseInt(chartsWarp.value.clientWidth);
var ss = parseInt(acct * reference * 1.3);
var color = colors[i];
var item = {
name: datas[i].name,
value: datas[i].value,
symbolSize: ss,
draggable: true,
itemStyle: {
normal: {
shadowBlur: 10,
shadowColor: color,
color: color,
},
},
};
seriesData.push(item);
}
console.info('seriesData', seriesData);
}
});
const data = ref([
{ value: 40, name: '一级', reaVal: '20' },
{ value: 80, name: '二级', reaVal: '30' },
{ value: 120, name: '三级', reaVal: '50' },
]);
const option = reactive({});
onMounted(() => {});
</script>
<style lang="scss" scoped>
.hot-charts {