合并所有平台
This commit is contained in:
parent
58cb3ebbf4
commit
313705c4c0
2
new-digital-agriculture-screen/.vscode/settings.json
vendored
Normal file
2
new-digital-agriculture-screen/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
{
|
||||
}
|
1
new-digital-agriculture-screen/.yarnrc.yml
Normal file
1
new-digital-agriculture-screen/.yarnrc.yml
Normal file
@ -0,0 +1 @@
|
||||
nodeLinker: node-modules
|
@ -42,6 +42,7 @@ declare module 'vue' {
|
||||
CustomScrollTitle: typeof import('./src/components/custom-scroll-title/index.vue')['default']
|
||||
CustomTableOperate: typeof import('./src/components/custom-table-operate/index.vue')['default']
|
||||
CustomTableTree: typeof import('./src/components/custom-table-tree/index.vue')['default']
|
||||
NewHyalineCake: typeof import('./src/components/custom-echart-hyaline-cake/new-hyaline-cake.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
SubTop: typeof import('./src/components/subTop.vue')['default']
|
||||
|
13213
new-digital-agriculture-screen/package-lock.json
generated
Normal file
13213
new-digital-agriculture-screen/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -17,6 +17,8 @@
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@smallwei/avue": "^3.6.2",
|
||||
"@vuemap/vue-amap": "^2.0",
|
||||
"@vuemap/vue-amap-loca": "^2.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"animate.css": "^4.1.1",
|
||||
@ -25,8 +27,6 @@
|
||||
"echarts-gl": "^2.0.9",
|
||||
"echarts-liquidfill": "^3.1.0",
|
||||
"echarts-wordcloud": "^2.1.0",
|
||||
"@vuemap/vue-amap": "^2.0",
|
||||
"@vuemap/vue-amap-loca": "^2.0",
|
||||
"element-plus": "^2.7.2",
|
||||
"js-base64": "^3.7.6",
|
||||
"lodash": "^4.17.21",
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
@ -128,11 +128,11 @@ export default {
|
||||
option.series[1].data = yDataLine.value;
|
||||
option.xAxis.data = xData.value;
|
||||
setOptions(option);
|
||||
// startAutoPlay({
|
||||
// interval: 2000,
|
||||
// seriesIndex: 0,
|
||||
// showTooltip: true,
|
||||
// });
|
||||
startAutoPlay({
|
||||
interval: 2000,
|
||||
seriesIndex: 0,
|
||||
showTooltip: true,
|
||||
});
|
||||
getInstance()?.off('click', onClick);
|
||||
getInstance()?.on('click', onClick);
|
||||
}
|
||||
|
@ -183,7 +183,9 @@ export default {
|
||||
const option = Object.assign(
|
||||
{
|
||||
tooltip: {
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||
// tooltip样式调整添加这个类名
|
||||
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||
borderColor: '#35d0c0',
|
||||
color: '#fff',
|
||||
position: function (point, params, dom, rect, size) {
|
||||
|
@ -0,0 +1,492 @@
|
||||
<template>
|
||||
<div ref="chartRef" :style="{ width: width, height: height }"></div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, onMounted, nextTick } from 'vue';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { useEcharts } from '@/hooks/useEcharts';
|
||||
|
||||
defineOptions({ name: 'NewHyalineCake' });
|
||||
|
||||
// 定义组件 props
|
||||
const props = defineProps({
|
||||
chartData: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
// 默认示例数据
|
||||
{ name: '项目一', value: 60 },
|
||||
{ name: '项目二', value: 44 },
|
||||
{ name: '项目三', value: 32 },
|
||||
],
|
||||
},
|
||||
option: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
// 控制内外径关系的系数,1 表示无内径(实心饼),值越小内径越大
|
||||
k: 1,
|
||||
// 扇形边缘向外偏移距离比例(用于选中效果),单位视图坐标,可调
|
||||
itemGap: 0.2,
|
||||
// 扇形高度(影响z轴拉伸程度)
|
||||
itemHeight: 120,
|
||||
// 自动计算扇形高度时使用的系数(>0时 itemHeight 失效,使用 autoItemHeight * value )
|
||||
autoItemHeight: 0,
|
||||
// 透明度设置
|
||||
opacity: 0.6,
|
||||
// 图例后缀
|
||||
legendSuffix: '',
|
||||
}),
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%',
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '100%',
|
||||
},
|
||||
});
|
||||
|
||||
// 声明组件触发的事件
|
||||
const emit = defineEmits(['click']);
|
||||
|
||||
// 绑定到DOM的容器引用
|
||||
const chartRef = ref(null);
|
||||
// 使用 useEcharts 钩子初始化 ECharts 实例,并获取控制方法
|
||||
const { setOptions, getInstance } = useEcharts(chartRef);
|
||||
|
||||
// 存储当前的 ECharts 配置项
|
||||
const chartOption = ref({});
|
||||
|
||||
// 参数方程函数:生成每个扇形曲面的参数方程,用于 series-surface.parametricEquation
|
||||
function getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
|
||||
// 中心弧度用于计算偏移方向
|
||||
const midRatio = (startRatio + endRatio) / 2;
|
||||
const startRadian = startRatio * Math.PI * 2;
|
||||
const endRadian = endRatio * Math.PI * 2;
|
||||
const midRadian = midRatio * Math.PI * 2;
|
||||
|
||||
// 如果整个饼只剩一个扇形,则不实现选中效果
|
||||
if (startRatio === 0 && endRatio === 1) {
|
||||
isSelected = false;
|
||||
}
|
||||
// k 取默认值 1/3(环的厚度比例),如果传入 k 则使用传入值
|
||||
k = typeof k !== 'undefined' ? k : 1 / 3;
|
||||
|
||||
// 计算选中效果的偏移量(基于扇形中心角度)
|
||||
const offsetX = isSelected ? Math.cos(midRadian) * props.option.itemGap : 0;
|
||||
const offsetY = isSelected ? Math.sin(midRadian) * props.option.itemGap : 0;
|
||||
// 计算高亮时的放大比例(未高亮时为1)
|
||||
const hoverRate = isHovered ? 1.05 : 1;
|
||||
|
||||
// 返回 parametric 曲面方程
|
||||
return {
|
||||
u: {
|
||||
// u 参数控制饼的周向角度:从 -π 到 3π,可以完整绘制一圈
|
||||
min: -Math.PI,
|
||||
max: Math.PI * 3,
|
||||
step: Math.PI / 32,
|
||||
},
|
||||
v: {
|
||||
// v 从 0 - 2π 参数控制扇形的径向方向(厚度方向)
|
||||
min: 0,
|
||||
max: Math.PI * 2,
|
||||
step: Math.PI / 20,
|
||||
},
|
||||
x(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(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(u, v) {
|
||||
// 在 u < -π/2 时,防止出现不必要的翻转,直接使用基本正弦
|
||||
if (u < -Math.PI * 0.5) {
|
||||
return Math.sin(u);
|
||||
}
|
||||
// 在 u > 2.5π 时,处理扇形尾部厚度
|
||||
if (u > Math.PI * 2.5) {
|
||||
return Math.sin(u) * h * 0.1;
|
||||
}
|
||||
// 正常情况下,z 根据 v 参数控制上下表面的高度差
|
||||
// 当前图形的高度是Z根据h(每个value的值决定的)
|
||||
return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// 生成整个 3D 饼图的配置项
|
||||
function getPie3D(pieData) {
|
||||
const series = [];
|
||||
let sumValue = 0;
|
||||
// 计算总值
|
||||
pieData.forEach((item) => {
|
||||
sumValue += item.value;
|
||||
});
|
||||
|
||||
// k 为外径厚度系数
|
||||
const k = props.option.k ?? 1;
|
||||
// 构建每个扇形的 series 数据
|
||||
pieData.forEach((dataItem, idx) => {
|
||||
const seriesItem = {
|
||||
name: dataItem.name ?? `series${idx}`,
|
||||
type: 'surface',
|
||||
parametric: true,
|
||||
wireframe: { show: false },
|
||||
pieData: dataItem,
|
||||
itemStyle: {
|
||||
opacity: props.option.opacity,
|
||||
borderRadius: 300,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 0,
|
||||
},
|
||||
pieStatus: {
|
||||
selected: false,
|
||||
hovered: false,
|
||||
k,
|
||||
},
|
||||
};
|
||||
// 合并自定义样式(如果有)
|
||||
if (dataItem.itemStyle) {
|
||||
const customStyle = {};
|
||||
if (dataItem.itemStyle.color !== undefined) {
|
||||
customStyle.color = dataItem.itemStyle.color;
|
||||
}
|
||||
if (dataItem.itemStyle.opacity !== undefined) {
|
||||
customStyle.opacity = dataItem.itemStyle.opacity;
|
||||
}
|
||||
seriesItem.itemStyle = { ...seriesItem.itemStyle, ...customStyle };
|
||||
}
|
||||
series.push(seriesItem);
|
||||
});
|
||||
|
||||
// 计算每个扇形的 startRatio/endRatio 和参数方程
|
||||
let startValue = 0;
|
||||
series.forEach((serie) => {
|
||||
const endValue = startValue + serie.pieData.value;
|
||||
const startRatio = startValue / sumValue;
|
||||
const endRatio = endValue / sumValue;
|
||||
serie.pieData.startRatio = startRatio;
|
||||
serie.pieData.endRatio = endRatio;
|
||||
// 初始均为未选中未高亮
|
||||
serie.parametricEquation = getParametricEquation(
|
||||
startRatio,
|
||||
endRatio,
|
||||
false,
|
||||
true,
|
||||
k,
|
||||
// 扇形高度:根据配置自动计算或使用固定高度
|
||||
props.option.autoItemHeight > 0 ? props.option.autoItemHeight * serie.pieData.value : props.option.itemHeight
|
||||
);
|
||||
startValue = endValue;
|
||||
});
|
||||
|
||||
// 添加一个透明圆环,用于实现 hover 在扇形外面时取消高亮
|
||||
series.push({
|
||||
name: 'mouseoutSeries',
|
||||
type: 'surface',
|
||||
parametric: true,
|
||||
wireframe: { show: false },
|
||||
itemStyle: { opacity: 0 },
|
||||
parametricEquation: {
|
||||
u: { min: 0, max: Math.PI * 2, step: Math.PI / 20 },
|
||||
v: { min: 0, max: Math.PI, step: Math.PI / 20 },
|
||||
x(u, v) {
|
||||
return Math.sin(v) * Math.sin(u) + Math.sin(u);
|
||||
},
|
||||
y(u, v) {
|
||||
return Math.sin(v) * Math.cos(u) + Math.cos(u);
|
||||
},
|
||||
z(u, v) {
|
||||
return Math.cos(v) > 0 ? 0.1 : -0.1;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 基础配置:坐标轴、视角、图例、提示框等
|
||||
const option = Object.assign(
|
||||
{
|
||||
tooltip: {
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8)',
|
||||
borderColor: '#35d0c0',
|
||||
color: '#fff',
|
||||
position: (point, params, dom, rect, size) => {
|
||||
// 动态调整 tooltip 位置,避免溢出
|
||||
let x = point[0],
|
||||
y = point[1];
|
||||
const [viewW, viewH] = size.viewSize;
|
||||
const [boxW, boxH] = size.contentSize;
|
||||
if (x + boxW > viewW) x -= boxW;
|
||||
if (y + boxH > viewH) y -= boxH;
|
||||
if (x < 0) x = 0;
|
||||
if (y < 0) y = 0;
|
||||
return [x, y];
|
||||
},
|
||||
formatter: (params) => {
|
||||
// 只对非透明环(实际扇形)显示信息
|
||||
if (params.seriesName !== 'mouseoutSeries') {
|
||||
return `
|
||||
<span style="color:#FFF">
|
||||
${params.seriesName}<br/>
|
||||
<span style="
|
||||
display:inline-block;
|
||||
margin-right:5px;
|
||||
border-radius:10px;
|
||||
width:10px;
|
||||
height:10px;
|
||||
background-color:${params.color};"></span>
|
||||
${chartOption.value.series[params.seriesIndex].pieData.value}
|
||||
</span>`;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
xAxis3D: { min: -1, max: 1 },
|
||||
yAxis3D: { min: -1, max: 1 },
|
||||
zAxis3D: { min: -1, max: 1 },
|
||||
grid3D: {
|
||||
show: false,
|
||||
boxHeight: 5,
|
||||
top: '0',
|
||||
left: '-20%',
|
||||
viewControl: {
|
||||
// 3D 视角设置
|
||||
alpha: 60, // 俯仰角度
|
||||
distance: 240, // 视角距离
|
||||
rotateSensitivity: 10,
|
||||
zoomSensitivity: 10,
|
||||
panSensitivity: 10,
|
||||
autoRotate: true,
|
||||
autoRotateAfterStill: 2,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
selectedMode: false,
|
||||
right: '5%',
|
||||
top: '25%',
|
||||
orient: 'vertical',
|
||||
icon: 'circle',
|
||||
itemHeight: 12,
|
||||
itemWidth: 12,
|
||||
itemGap: 10,
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 14,
|
||||
fontWeight: '400',
|
||||
},
|
||||
// 图例标签显示名称和数值
|
||||
formatter: (name) => {
|
||||
const item = props.chartData.find((d) => d.name === name);
|
||||
return item ? ` ${name} ${item.value}${props.option.legendSuffix || ''}` : name;
|
||||
},
|
||||
},
|
||||
series,
|
||||
},
|
||||
// 将外部配置项覆盖基础配置
|
||||
props.option
|
||||
);
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
// 初始化图表
|
||||
function initChart() {
|
||||
// 生成基础的3D饼图配置
|
||||
const baseOption = getPie3D(props.chartData);
|
||||
// 合并用户配置,确保不修改原始对象
|
||||
const finalOption = Object.assign({}, baseOption, cloneDeep(props.option || {}));
|
||||
chartOption.value = finalOption;
|
||||
// 设置图表配置
|
||||
setOptions(chartOption.value);
|
||||
// 等待 DOM + ECharts 初始化完成
|
||||
nextTick(() => {
|
||||
const chart = getInstance();
|
||||
if (!chart) {
|
||||
console.warn('ECharts 实例未初始化,事件绑定失败');
|
||||
return;
|
||||
}
|
||||
|
||||
// 避免重复绑定事件
|
||||
chart.off('click');
|
||||
chart.off('mouseover');
|
||||
chart.off('globalout');
|
||||
|
||||
chart.on('click', handleClick);
|
||||
chart.on('mouseover', handleMouseover);
|
||||
chart.on('globalout', handleGlobalout);
|
||||
});
|
||||
}
|
||||
function handleClick(params) {
|
||||
// 如果点击的是透明辅助环,则忽略
|
||||
if (params.seriesName === 'mouseoutSeries') return;
|
||||
|
||||
const optionVal = chartOption.value;
|
||||
const series = optionVal.series;
|
||||
const idx = params.seriesIndex;
|
||||
|
||||
// 新的选中状态(取反)
|
||||
const isSelected = !series[idx].pieStatus.selected;
|
||||
const isHovered = series[idx].pieStatus.hovered;
|
||||
const k = series[idx].pieStatus.k;
|
||||
const startRatio = series[idx].pieData.startRatio;
|
||||
const endRatio = series[idx].pieData.endRatio;
|
||||
const h = series[idx].pieData.value;
|
||||
|
||||
// 如果之前有其他扇形被选中,取消其选中状态
|
||||
if (selectedIndex !== null && selectedIndex !== idx) {
|
||||
const prev = series[selectedIndex];
|
||||
prev.parametricEquation = getParametricEquation(
|
||||
prev.pieData.startRatio,
|
||||
prev.pieData.endRatio,
|
||||
false,
|
||||
false,
|
||||
prev.pieStatus.k,
|
||||
prev.pieData.value
|
||||
);
|
||||
prev.pieStatus.selected = false;
|
||||
selectedIndex = null;
|
||||
}
|
||||
|
||||
// 设置当前扇形的选中/取消选中状态
|
||||
series[idx].parametricEquation = getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h);
|
||||
series[idx].pieStatus.selected = isSelected;
|
||||
|
||||
// 更新记录选中的系列索引
|
||||
selectedIndex = isSelected ? idx : null;
|
||||
|
||||
// 更新图表配置
|
||||
setOptions(optionVal);
|
||||
// 触发组件 click 事件供父组件使用
|
||||
emit('click', params);
|
||||
}
|
||||
// 在函数顶部声明(确保作用域覆盖所有需要的地方)
|
||||
window.debugZValues = {
|
||||
current: null,
|
||||
history: [],
|
||||
};
|
||||
function handleMouseover(params) {
|
||||
if (params.seriesName === 'mouseoutSeries') return;
|
||||
|
||||
const chart = getInstance();
|
||||
const optionVal = chart.getOption(); // 改用实时获取最新配置
|
||||
const series = optionVal.series;
|
||||
const idx = params.seriesIndex;
|
||||
const hh = series[idx].parametricEquation.z();
|
||||
window.debugZValues.current = hh;
|
||||
window.debugZValues.history.push({
|
||||
event: 'mouseover',
|
||||
series: series[idx].name,
|
||||
zValue: hh,
|
||||
time: new Date().toISOString(),
|
||||
});
|
||||
console.log('当前Z值:', hh, '历史记录:', window.debugZValues.history);
|
||||
// 打印移入前的完整状态(调试用)
|
||||
console.log(
|
||||
'[移入] 当前所有扇形状态',
|
||||
series.map((s) => ({
|
||||
name: s.name,
|
||||
hovered: s.pieStatus?.hovered,
|
||||
selected: s.pieStatus?.selected,
|
||||
height: s.parametricEquation?.z(Math.PI, Math.PI),
|
||||
}))
|
||||
);
|
||||
|
||||
// 取消之前的高亮(确保只修改状态,不破坏参数方程)
|
||||
if (hoveredIndex !== null && hoveredIndex !== idx) {
|
||||
const prev = series[hoveredIndex];
|
||||
prev.pieStatus.hovered = false; // 仅修改状态
|
||||
prev.parametricEquation = getParametricEquation(
|
||||
// 重新生成正确方程
|
||||
prev.pieData.startRatio,
|
||||
prev.pieData.endRatio,
|
||||
prev.pieStatus.selected,
|
||||
false, // isHovered=false
|
||||
prev.pieStatus.k,
|
||||
prev.pieData.value
|
||||
);
|
||||
}
|
||||
|
||||
// 设置新高亮
|
||||
const current = series[idx];
|
||||
current.pieStatus.hovered = true;
|
||||
current.parametricEquation = getParametricEquation(
|
||||
current.pieData.startRatio,
|
||||
current.pieData.endRatio,
|
||||
current.pieStatus.selected,
|
||||
true, // isHovered=true
|
||||
current.pieStatus.k,
|
||||
current.pieData.value
|
||||
);
|
||||
|
||||
hoveredIndex = idx;
|
||||
chart.setOption({ series }); // 仅更新series部分
|
||||
}
|
||||
function handleGlobalout() {
|
||||
if (hoveredIndex !== null) {
|
||||
const chart = getInstance();
|
||||
const optionVal = chart.getOption();
|
||||
const series = optionVal.series;
|
||||
const prev = series[hoveredIndex];
|
||||
|
||||
// 打印修复前的错误状态(调试用)
|
||||
console.warn('[修复前] 异常状态', {
|
||||
name: prev.name,
|
||||
z: prev.parametricEquation.z(Math.PI, Math.PI),
|
||||
equation: prev.parametricEquation,
|
||||
});
|
||||
|
||||
// 重置状态并重新生成方程
|
||||
prev.pieStatus.hovered = false;
|
||||
prev.parametricEquation = getParametricEquation(
|
||||
prev.pieData.startRatio,
|
||||
prev.pieData.endRatio,
|
||||
prev.pieStatus.selected,
|
||||
false, // isHovered=false
|
||||
prev.pieStatus.k,
|
||||
prev.pieData.value
|
||||
);
|
||||
|
||||
hoveredIndex = null;
|
||||
chart.setOption({ series }, { replaceMerge: 'series' }); // 强制替换series
|
||||
}
|
||||
}
|
||||
// 记录当前选中和高亮的系列索引
|
||||
let selectedIndex = null;
|
||||
let hoveredIndex = null;
|
||||
|
||||
// 组件挂载后绑定事件
|
||||
onMounted(() => {
|
||||
initChart();
|
||||
});
|
||||
|
||||
// 监听数据或配置变更,重新初始化图表
|
||||
watch(
|
||||
[() => props.chartData, () => props.option],
|
||||
() => {
|
||||
if (props.chartData && props.chartData.length) {
|
||||
initChart();
|
||||
}
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 可根据需要自定义图表容器样式 */
|
||||
</style>
|
@ -36,10 +36,10 @@ export default {
|
||||
const { setOptions, getInstance, resize, startAutoPlay } = useEcharts(chartRef);
|
||||
const option = reactive({
|
||||
tooltip: {
|
||||
// trigger: 'axis',
|
||||
// axisPointer: {
|
||||
// type: 'shadow',
|
||||
// },
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||
borderColor: '#35d0c0',
|
||||
formatter: (data) => {
|
||||
@ -56,28 +56,62 @@ export default {
|
||||
zlevel: 1,
|
||||
name: '漏斗图',
|
||||
type: 'funnel',
|
||||
top: '11%',
|
||||
left: 'center',
|
||||
width: '28%',
|
||||
width: '25%',
|
||||
sort: 'ascending',
|
||||
gap: 0,
|
||||
label: {
|
||||
show: true,
|
||||
position: 'right',
|
||||
position: 'outside',
|
||||
width: '200px',
|
||||
align: 'right',
|
||||
formatter: function (params) {
|
||||
if (!params.data.reaVal) return '';
|
||||
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' },
|
||||
b: { color: '#05FCC6', fontSize: '16px', marginTop: '10px' },
|
||||
},
|
||||
verticalAlign: 'middle',
|
||||
padding: [5, 6], // 增加标签内边距
|
||||
},
|
||||
labelLine: {
|
||||
show: false,
|
||||
show: true,
|
||||
length: 10,
|
||||
length2: 50,
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: '#ffffff',
|
||||
opacity: 1,
|
||||
type: 'solid',
|
||||
},
|
||||
},
|
||||
// 添加第二段折线
|
||||
// markLine: {
|
||||
// symbol: 'none', // 隐藏端点
|
||||
// lineStyle: {
|
||||
// type: 'solid',
|
||||
// color: '#fff',
|
||||
// width: 1,
|
||||
// },
|
||||
// data: [
|
||||
// // 从默认 labelLine 的终点到自定义位置
|
||||
// [
|
||||
// {
|
||||
// coord: [50, 50], // 第一段线的终点(需动态计算)
|
||||
// name: 'Label1',
|
||||
// },
|
||||
// {
|
||||
// coord: [80, 50], // 第二段线的终点
|
||||
// name: 'Label1',
|
||||
// },
|
||||
// ],
|
||||
// ],
|
||||
// },
|
||||
itemStyle: {
|
||||
show: false,
|
||||
borderColor: '#fff',
|
||||
|
@ -204,6 +204,7 @@ onUnmounted(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
flex: none;
|
||||
.rank {
|
||||
margin-right: 5px;
|
||||
}
|
||||
@ -212,7 +213,7 @@ onUnmounted(() => {
|
||||
}
|
||||
}
|
||||
.ranking-column {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
.inside-column {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
@ -69,7 +69,7 @@ const props = defineProps({
|
||||
});
|
||||
const titleContentW = ref('0');
|
||||
const itemW = ref('1');
|
||||
const gap = ref(24);
|
||||
const gap = ref(1);
|
||||
const leftNum = ref(0);
|
||||
const position = ref(0);
|
||||
const right = ref(null);
|
||||
@ -133,7 +133,7 @@ function handleTitleClick(val) {
|
||||
.header_title {
|
||||
background-color: #000;
|
||||
position: relative;
|
||||
padding: 0 68px;
|
||||
padding: 0 40px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100vw;
|
||||
@ -174,7 +174,7 @@ function handleTitleClick(val) {
|
||||
.left_titles_container,
|
||||
.right_titles_container {
|
||||
position: relative;
|
||||
width: 30%;
|
||||
width: 31%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
line-height: 90px;
|
||||
@ -182,10 +182,10 @@ function handleTitleClick(val) {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
width: var(--titleContentW);
|
||||
height: 40px;
|
||||
height: 56px;
|
||||
transition: all 0.4s ease;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
font-size: 24px;
|
||||
// font-weight: bold;
|
||||
.active {
|
||||
color: #fff;
|
||||
opacity: 1 !important;
|
||||
@ -194,9 +194,9 @@ function handleTitleClick(val) {
|
||||
.title_item {
|
||||
margin-right: var(--gap);
|
||||
display: inline-block;
|
||||
width: var(--itemW);
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
min-width: var(--itemW);
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
text-align: center;
|
||||
color: #f5fffe;
|
||||
cursor: pointer;
|
||||
|
@ -9,7 +9,7 @@
|
||||
></div>
|
||||
<span class="title-top-content" :style="{ 'text-align': props.left }">{{ topTitle || '--' }}</span>
|
||||
<div v-if="isDown" class="down-list" :style="{ width: downWidth }">
|
||||
<el-dropdown :hide-on-click="true" :style="{ width: '90%' }" trigger="click" @command="handleCommand">
|
||||
<el-dropdown :hide-on-click="true" trigger="click" @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
{{ currentVal && currentVal[labelField] ? currentVal[labelField] : downTitle }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||
</span>
|
||||
@ -147,15 +147,15 @@ const handleCommand = (data) => {
|
||||
}
|
||||
.title-top-content {
|
||||
line-height: 38px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
// font-weight: bold;
|
||||
display: inline-block;
|
||||
transform: skewX(-13deg);
|
||||
background: linear-gradient(to bottom, '#ff7e5f', '#548fff');
|
||||
-webkit-background-clip: text;
|
||||
color: #fff;
|
||||
letter-spacing: 4px;
|
||||
text-shadow: -2px 0 0 1px #add8f1;
|
||||
text-shadow: -2px 0 10px #add8f1;
|
||||
width: 100%;
|
||||
padding: 0 36px 0 72px;
|
||||
box-sizing: border-box;
|
||||
@ -167,7 +167,7 @@ const handleCommand = (data) => {
|
||||
.down-list {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
right: 32px;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 2;
|
||||
@ -178,6 +178,8 @@ const handleCommand = (data) => {
|
||||
border: 1px solid $color-custom-main;
|
||||
padding: 6px;
|
||||
border-radius: 4px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,9 @@ import echarts from '../utils/echarts';
|
||||
|
||||
export const useEcharts = (elRef, theme = 'default') => {
|
||||
// 新增轮播相关状态
|
||||
const autoPlayTimer = ref(null);
|
||||
const currentIndex = ref(-1);
|
||||
const dataLength = ref(0);
|
||||
const autoPlayTimer = ref(null); // 定时器句柄
|
||||
const currentIndex = ref(-1); // 当前高亮的数据索引
|
||||
const dataLength = ref(0); // 当前系列的数据总长度
|
||||
|
||||
let mapClickHandler = null;
|
||||
|
||||
@ -18,29 +18,41 @@ export const useEcharts = (elRef, theme = 'default') => {
|
||||
const {
|
||||
interval = 2000, // 轮播间隔(ms)
|
||||
seriesIndex = 0, // 默认操作第一个系列
|
||||
showTooltip = true, // 是否显示提示框
|
||||
showTooltip = false, // 是否显示提示框,默认是false,外部配置了,无论是否true都会显示
|
||||
showMarkPoint = true, // 是否显示默认的动态标记点
|
||||
} = options;
|
||||
|
||||
stopAutoPlay(); // 先停止已有轮播
|
||||
|
||||
// 获取数据长度
|
||||
// 获取当前系列的数据长度
|
||||
const seriesData = unref(getOptions).series?.[seriesIndex]?.data;
|
||||
const xAxisData = unref(getOptions).xAxis?.data || [];
|
||||
// 获取当前 option 中的 yAxis 类型来判断是否倒置
|
||||
const axisType = unref(getOptions).yAxis?.type;
|
||||
const isCategoryY = axisType === 'category';
|
||||
|
||||
dataLength.value = seriesData?.length || 0;
|
||||
if (dataLength.value === 0) return;
|
||||
|
||||
autoPlayTimer.value = setInterval(() => {
|
||||
currentIndex.value = (currentIndex.value + 1) % dataLength.value;
|
||||
// 更新MarkPoint点信息
|
||||
if (showMarkPoint) {
|
||||
updateMarkPoint(currentIndex.value, xAxisData, seriesData, isCategoryY);
|
||||
}
|
||||
|
||||
// 执行轮播动作
|
||||
// 重置之前的高亮
|
||||
chartInstance?.dispatchAction({
|
||||
type: 'downplay',
|
||||
seriesIndex: seriesIndex,
|
||||
});
|
||||
// 高亮当前项
|
||||
chartInstance?.dispatchAction({
|
||||
type: 'highlight',
|
||||
seriesIndex: seriesIndex,
|
||||
dataIndex: currentIndex.value,
|
||||
});
|
||||
// 显示 tooltip(可选)
|
||||
if (showTooltip) {
|
||||
chartInstance?.dispatchAction({
|
||||
type: 'showTip',
|
||||
@ -51,6 +63,40 @@ export const useEcharts = (elRef, theme = 'default') => {
|
||||
}, interval);
|
||||
};
|
||||
|
||||
function updateMarkPoint(index, xAxis, seriesData, isCategoryY) {
|
||||
const x = isCategoryY ? seriesData[index] : xAxis[index];
|
||||
const y = isCategoryY ? xAxis[index] : seriesData[index];
|
||||
const updatedSeries = chartInstance.getOption().series;
|
||||
|
||||
if (updatedSeries[0].markPoint && Array.isArray(updatedSeries[0].markPoint.data) && updatedSeries[0].markPoint.data.length > 1) {
|
||||
// 已初始化:只改坐标
|
||||
updatedSeries[0].markPoint.data.forEach((el) => {
|
||||
el.coord = [x, y];
|
||||
});
|
||||
} else {
|
||||
// 未初始化或数据不对:重建
|
||||
updatedSeries[0].markPoint = {
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
itemStyle: {
|
||||
color: '#ffffff',
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
data: [
|
||||
{ coord: [x, y], symbolSize: 16, itemStyle: { color: '#ffffff' }, z: 12 },
|
||||
{ coord: [x, y], symbolSize: 24, itemStyle: { color: 'rgba(1, 238, 255, 0.5)' }, z: 11 },
|
||||
{ coord: [x, y], symbolSize: 40, itemStyle: { color: 'rgba(1, 238, 255, 0.3)' }, z: 10 },
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
chartInstance.setOption({
|
||||
series: updatedSeries,
|
||||
});
|
||||
}
|
||||
|
||||
// 新增方法 - 停止轮播
|
||||
const stopAutoPlay = () => {
|
||||
if (autoPlayTimer.value) {
|
||||
|
@ -74,6 +74,7 @@ onMounted(() => {
|
||||
}
|
||||
.base-laytout-header {
|
||||
height: 90px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -9,6 +9,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
.custom-tooltip-container{
|
||||
border-radius: 8px !important;
|
||||
padding: 6px 16px 6px 8px !important;
|
||||
background-color: rgba(0,0,0,0.7) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
& span{
|
||||
width: 8px !important;
|
||||
height: 8px !important;
|
||||
vertical-align: middle;
|
||||
margin-top: -4px;
|
||||
}
|
||||
}
|
||||
.custom-echarts-tips {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,9 @@ import {
|
||||
CalendarComponent,
|
||||
GraphicComponent,
|
||||
GeoComponent,
|
||||
MarkPointComponent,
|
||||
MarkLineComponent,
|
||||
MarkAreaComponent,
|
||||
} from 'echarts/components';
|
||||
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
@ -64,6 +67,9 @@ echarts.use([
|
||||
ScatterChart,
|
||||
EffectScatterChart,
|
||||
GeoComponent,
|
||||
MarkPointComponent,
|
||||
MarkLineComponent,
|
||||
MarkAreaComponent,
|
||||
]);
|
||||
|
||||
export default echarts;
|
||||
|
@ -40,6 +40,7 @@ router.beforeEach(async (to, from, next) => {
|
||||
return;
|
||||
}
|
||||
next();
|
||||
next();
|
||||
}
|
||||
} catch (error) {
|
||||
next(`/login?redirect=${to.path}`);
|
||||
|
@ -127,7 +127,7 @@ watch(
|
||||
width: 160px;
|
||||
margin: 0 auto;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
line-height: 26px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
|
@ -199,7 +199,9 @@ function getPie3D(pieData, internalDiameterRatio) {
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||
// tooltip样式调整添加这个类名
|
||||
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||
borderColor: '#35d0c0',
|
||||
color: '#fff',
|
||||
position: function (point, params, dom, rect, size) {
|
||||
|
@ -27,7 +27,9 @@ const state = reactive({
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||
// tooltip样式调整添加这个类名
|
||||
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||
borderColor: '#35d0c0',
|
||||
formatter: (data) => {
|
||||
const params = data[0];
|
||||
|
@ -30,7 +30,9 @@ const state = reactive({
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||
// tooltip样式调整添加这个类名
|
||||
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||
borderColor: '#35d0c0',
|
||||
formatter: (data) => {
|
||||
const params = data[0];
|
||||
|
@ -145,6 +145,7 @@ function handleChange(n) {
|
||||
top: 8px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
text-shadow: 2px 0px 10px 0px #01eeff;
|
||||
}
|
||||
.left_btn {
|
||||
left: 6px;
|
||||
|
@ -1,39 +1,60 @@
|
||||
<template>
|
||||
<customEchartHyalineCake :chart-data="data" height="100%" :option="option" />
|
||||
<customEchartHyalineCake ref="chartRef" :chart-data="data" height="100%" :option="option" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
const chartRef = ref(null);
|
||||
|
||||
/* --------------- data --------------- */
|
||||
/* --------------- data右上侧饼图 --------------- */
|
||||
// #region
|
||||
const data = ref([
|
||||
{
|
||||
name: '企业',
|
||||
name: ' 企业',
|
||||
value: 10.8,
|
||||
itemStyle: { color: '#5b7bc7', opacity: 0.8 },
|
||||
},
|
||||
{
|
||||
name: '合作社',
|
||||
value: 8.4,
|
||||
name: ' 合作社',
|
||||
value: 18.4,
|
||||
itemStyle: { color: '#8ed0f3', opacity: 0.8 },
|
||||
},
|
||||
{
|
||||
name: '村集体',
|
||||
value: 4.3,
|
||||
name: ' 村集体',
|
||||
value: 14.3,
|
||||
itemStyle: { color: '#65be97', opacity: 0.8 },
|
||||
},
|
||||
{
|
||||
name: '个体',
|
||||
value: 3.7,
|
||||
name: ' 个体',
|
||||
value: 23.7,
|
||||
itemStyle: { color: '#f0c94d', opacity: 0.8 },
|
||||
},
|
||||
]);
|
||||
|
||||
let itemGapWith = ref(0);
|
||||
const getChartrefWith = () => {
|
||||
let len = data.value.length * 2;
|
||||
return chartRef.value.$refs.chartRef.offsetWidth / len + 8;
|
||||
};
|
||||
|
||||
const option = reactive({
|
||||
k: 0.2,
|
||||
opacity: 0.6,
|
||||
opacity: 0.4,
|
||||
itemGap: 0,
|
||||
autoItemHeight: 3,
|
||||
legend: {
|
||||
type: 'plain',
|
||||
orient: 'horizontal',
|
||||
width: '100%',
|
||||
bottom: 10,
|
||||
left: 'center',
|
||||
itemWidth: 16,
|
||||
itemHeight: 16,
|
||||
itemGap: itemGapWith.value ? itemGapWith.value : 50,
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: '16px',
|
||||
},
|
||||
},
|
||||
title: {
|
||||
text: '23亿元',
|
||||
@ -47,18 +68,18 @@ const option = reactive({
|
||||
color: '#02FD94',
|
||||
fontSize: '18px',
|
||||
},
|
||||
top: 'center',
|
||||
top: '26%',
|
||||
left: 'center',
|
||||
},
|
||||
grid3D: {
|
||||
show: false,
|
||||
boxHeight: 5,
|
||||
top: 'center',
|
||||
boxHeight: 3,
|
||||
top: '-15%', //调整距离顶部距离,0是在中间
|
||||
left: 'center',
|
||||
viewControl: {
|
||||
//3d效果可以放大、旋转等,请自己去查看官方配置
|
||||
alpha: 30, //角度(这个很重要 调节角度的)
|
||||
distance: 160, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||
alpha: 36, //角度(这个很重要 调节角度的)
|
||||
distance: 130, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||
rotateSensitivity: 10, //设置旋转灵敏度,为0无法旋转
|
||||
zoomSensitivity: 10, //设置缩放灵敏度,为0无法缩放
|
||||
panSensitivity: 10, //设置平移灵敏度,0无法平移
|
||||
@ -73,6 +94,10 @@ const option = reactive({
|
||||
// #region
|
||||
|
||||
// #endregion
|
||||
onMounted(() => {
|
||||
itemGapWith.value = getChartrefWith();
|
||||
option.legend.itemGap = itemGapWith.value ? itemGapWith.value : 50;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
@ -1,34 +1,21 @@
|
||||
<template>
|
||||
<custom-echart-line :chart-data="dataList" height="100%" :option="state.option" />
|
||||
<custom-echart-line :chart-data="state.data" height="100%" :option="state.option" />
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive } from 'vue';
|
||||
let dataList = reactive([
|
||||
{
|
||||
value: 10,
|
||||
name: '2020',
|
||||
import { reactive, watch } from 'vue';
|
||||
import { isEmpty, sleep } from '@/utils';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
{
|
||||
value: 66,
|
||||
name: '2021',
|
||||
query: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
value: 100,
|
||||
name: '2022',
|
||||
},
|
||||
{
|
||||
value: 120,
|
||||
name: '2023',
|
||||
},
|
||||
{
|
||||
value: 150,
|
||||
name: '2024',
|
||||
},
|
||||
{
|
||||
value: 80,
|
||||
name: '2025',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
const state = reactive({
|
||||
option: {
|
||||
color: ['#35D0C0'],
|
||||
@ -44,7 +31,9 @@ const state = reactive({
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||
// tooltip样式调整添加这个类名
|
||||
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||
backgroundColor: 'rgba(0,0,0,0.5);',
|
||||
borderColor: '#35d0c0',
|
||||
formatter: (data) => {
|
||||
const params = data[0];
|
||||
@ -76,12 +65,12 @@ const state = reactive({
|
||||
// name: '',
|
||||
},
|
||||
},
|
||||
data: dataList,
|
||||
data: [],
|
||||
});
|
||||
|
||||
const refresData = () => {
|
||||
console.info('landPatrol********************refresData');
|
||||
state.data = dataList = reactive([
|
||||
// console.info('landPatrol********************refresData');
|
||||
state.data = reactive([
|
||||
{
|
||||
value: 20,
|
||||
name: '2020',
|
||||
@ -108,7 +97,53 @@ const refresData = () => {
|
||||
},
|
||||
]);
|
||||
};
|
||||
const loadData = async (code = '') => {
|
||||
state.loading = true;
|
||||
// GetInputsInfo()
|
||||
// .then((res) => {
|
||||
// if (res.code === 200) {
|
||||
// state.data = res.data;
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// app.$message.error(err.msg);
|
||||
// });
|
||||
await sleep(500);
|
||||
state.data = [
|
||||
{ value: 5, name: '2020' },
|
||||
{ value: 36, name: '2021' },
|
||||
{ value: 70, name: '2022' },
|
||||
{ value: 56, name: '2023' },
|
||||
{ value: 70, name: '2024' },
|
||||
{ value: 20, name: '2025' },
|
||||
];
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
(val) => {
|
||||
if (!isEmpty(val)) {
|
||||
state.data = val;
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.query,
|
||||
(val) => {
|
||||
if (!isEmpty(val)) {
|
||||
loadData(val);
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
defineExpose({
|
||||
refresData,
|
||||
});
|
||||
|
@ -2,43 +2,48 @@
|
||||
<custom-echart-column-line :chart-data="state.data" height="100%" :option="state.option" />
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive } from 'vue';
|
||||
import { reactive, watch } from 'vue';
|
||||
import { isEmpty, sleep } from '@/utils';
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
query: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const state = reactive({
|
||||
data: [
|
||||
{ value: 103, value1: 208, name: '耿马镇' },
|
||||
{ value: 72, value1: 157, name: '勐撒镇' },
|
||||
{ value: 50, value1: 125, name: '勐永镇' },
|
||||
{ value: 60, value1: 146, name: '孟定镇' },
|
||||
{ value: 40, value1: 86, name: '勐简乡' },
|
||||
{ value: 111, value1: 172, name: '贺派乡' },
|
||||
{ value: 81, value1: 180, name: '四排山乡' },
|
||||
{ value: 55, value1: 99, name: '芒洪乡' },
|
||||
{ value: 68, value1: 84, name: '大兴乡' },
|
||||
],
|
||||
data: [],
|
||||
option: {
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '10%',
|
||||
right: '1%',
|
||||
bottom: '10%',
|
||||
top: '15%',
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||
// tooltip样式调整添加这个类名
|
||||
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||
borderColor: '#35d0c0',
|
||||
formatter: (data) => {
|
||||
console.log('data', data);
|
||||
const params = data[0];
|
||||
let str = `<div class="custom-echarts-tips">
|
||||
<span>${params.name}</span><br/>
|
||||
<span>${params.marker} ${params.data} 万</span><br />
|
||||
<span>${data[1].marker} ${data[1].data} 万</span>
|
||||
<span>${params.marker} ${params.data} 万吨</span><br />
|
||||
<span>${data[1].marker} ${data[1].data} 万吨</span>
|
||||
</div>`;
|
||||
return str;
|
||||
},
|
||||
@ -130,14 +135,14 @@ const state = reactive({
|
||||
},
|
||||
],
|
||||
legend: {
|
||||
itemWidth: 12,
|
||||
itemHeight: 8,
|
||||
itemWidth: 16,
|
||||
itemHeight: 16,
|
||||
itemGap: 20,
|
||||
right: '2%',
|
||||
top: '3%',
|
||||
x: 'center',
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
fontSize: 16,
|
||||
color: '#fff',
|
||||
},
|
||||
data: ['总产量(吨)', '平均产量(吨)'],
|
||||
@ -156,12 +161,12 @@ const state = reactive({
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(53,208,192,1)',
|
||||
color: 'rgba(1,254,253,1)',
|
||||
},
|
||||
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(53,208,192,0)',
|
||||
color: 'rgba(1,254,253,0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
@ -180,23 +185,72 @@ const state = reactive({
|
||||
name: '平均产量(吨)',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
showSymbol: true,
|
||||
showSymbol: false,
|
||||
symbolSize: 8,
|
||||
smooth: true,
|
||||
smooth: false,
|
||||
symbol: 'circle',
|
||||
max: 100,
|
||||
lineStyle: {
|
||||
normal: {
|
||||
color: 'rgba(53,208,192,1)',
|
||||
color: '#FEF906',
|
||||
},
|
||||
},
|
||||
itemStyle: {
|
||||
color: 'rgba(254,249,6,1)',
|
||||
borderColor: '#fff',
|
||||
borderWidth: 1,
|
||||
color: '#FEF906',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const loadData = async (code = '') => {
|
||||
state.loading = true;
|
||||
// GetInputsInfo()
|
||||
// .then((res) => {
|
||||
// if (res.code === 200) {
|
||||
// state.data = res.data;
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// app.$message.error(err.msg);
|
||||
// });
|
||||
await sleep(500);
|
||||
state.data = [
|
||||
{ value: 103, value1: 102, name: '耿马镇' },
|
||||
{ value: 72, value1: 157, name: '勐撒镇' },
|
||||
{ value: 50, value1: 125, name: '勐永镇' },
|
||||
{ value: 60, value1: 146, name: '孟定镇' },
|
||||
{ value: 40, value1: 86, name: '勐简乡' },
|
||||
{ value: 111, value1: 172, name: '贺派乡' },
|
||||
{ value: 81, value1: 180, name: '四排山乡' },
|
||||
{ value: 55, value1: 66, name: '芒洪乡' },
|
||||
{ value: 68, value1: 84, name: '大兴乡' },
|
||||
];
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
(val) => {
|
||||
if (!isEmpty(val)) {
|
||||
state.data = val;
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.query,
|
||||
(val) => {
|
||||
if (!isEmpty(val)) {
|
||||
loadData(val);
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
@ -1,34 +1,40 @@
|
||||
<template>
|
||||
<customEchartHyalineCake :chart-data="data" height="100%" :option="option" />
|
||||
<customEchartHyalineCake :chart-data="dataList" height="100%" :option="option" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
|
||||
/* --------------- data --------------- */
|
||||
/* --------------- 左中饼图 --------------- */
|
||||
// #region
|
||||
const data = ref([
|
||||
const dataList = ref([
|
||||
{
|
||||
name: '烟草',
|
||||
value: 60.8,
|
||||
money: 100,
|
||||
},
|
||||
{
|
||||
name: '甘蔗',
|
||||
value: 44.4,
|
||||
money: 88,
|
||||
},
|
||||
{
|
||||
name: '核桃',
|
||||
value: 24.3,
|
||||
money: 92,
|
||||
},
|
||||
{
|
||||
name: '蔬菜',
|
||||
value: 32.7,
|
||||
money: 56,
|
||||
},
|
||||
{
|
||||
name: '其他',
|
||||
value: 32.9,
|
||||
money: 18,
|
||||
},
|
||||
]);
|
||||
|
||||
const option = reactive({
|
||||
k: 0.3,
|
||||
opacity: 1,
|
||||
@ -36,13 +42,13 @@ const option = reactive({
|
||||
autoItemHeight: 2,
|
||||
grid3D: {
|
||||
show: false,
|
||||
boxHeight: 5,
|
||||
top: '0',
|
||||
boxHeight: 4, //厚度
|
||||
top: '0', //距离顶部的距离
|
||||
left: '-20%',
|
||||
viewControl: {
|
||||
//3d效果可以放大、旋转等,请自己去查看官方配置
|
||||
alpha: 30, //角度(这个很重要 调节角度的)
|
||||
distance: 160, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||
distance: 200, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||
rotateSensitivity: 10, //设置旋转灵敏度,为0无法旋转
|
||||
zoomSensitivity: 10, //设置缩放灵敏度,为0无法缩放
|
||||
panSensitivity: 10, //设置平移灵敏度,0无法平移
|
||||
@ -50,6 +56,41 @@ const option = reactive({
|
||||
autoRotateAfterStill: 2, //在鼠标静止操作后恢复自动旋转的时间间隔,在开启 autoRotate 后有效
|
||||
},
|
||||
},
|
||||
// series: [
|
||||
// // 透明的 2D 饼图(仅用于生成标签折线)
|
||||
// {
|
||||
// type: 'pie',
|
||||
// radius: ['30%', '70%'],
|
||||
// center: ['40%', '50%'],
|
||||
// startAngle: -40, // 调整角度与 3D 图形对齐
|
||||
// clockwise: false,
|
||||
// label: {
|
||||
// show: true,
|
||||
// position: 'outside',
|
||||
// formatter: (params) => {
|
||||
// console.log(params);
|
||||
// return `{a|${params.data.name}}\n{b|${params.data.money}万元}`;
|
||||
// },
|
||||
// rich: {
|
||||
// a: { color: '#ffffff' },
|
||||
// b: { color: '#79F5AF' },
|
||||
// },
|
||||
// },
|
||||
// labelLine: {
|
||||
// show: true,
|
||||
// length: 10,
|
||||
// length2: 15,
|
||||
// lineStyle: {
|
||||
// color: '#ffffff',
|
||||
// width: 1,
|
||||
// },
|
||||
// },
|
||||
// data: dataList,
|
||||
// itemStyle: {
|
||||
// opacity: 1, // 隐藏扇区,仅保留标签和折线
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
});
|
||||
// #endregion
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<div ref="chartsWarp" class="hot-charts">
|
||||
<section class="_top_btns">
|
||||
<span class="left_btn" @click="handleChange(-1)"></span>
|
||||
<span class="right_btn" @click="handleChange(1)"></span>
|
||||
{{ current.info.name }}
|
||||
</section>
|
||||
<custom-echart-triangle :chart-data="data" height="100%" :option="option" />
|
||||
</div>
|
||||
</template>
|
||||
@ -7,15 +12,78 @@
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
|
||||
const data = ref([
|
||||
{ value: 40, name: '一级', reaVal: '20' },
|
||||
{ value: 80, name: '二级', reaVal: '30' },
|
||||
{ value: 120, name: '三级', reaVal: '50' },
|
||||
{ value: 40, name: '一级', reaVal: '20', itemStyle: { color: '#56b1c0' } },
|
||||
{ value: 80, name: '二级', reaVal: '30', itemStyle: { color: '#77c8ca' } },
|
||||
{ value: 120, name: '三级', reaVal: '50', itemStyle: { color: '#7bb9cf' } },
|
||||
]);
|
||||
const option = reactive({});
|
||||
onMounted(() => {});
|
||||
|
||||
const list = ref([
|
||||
{
|
||||
name: '茶叶',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
name: '核桃',
|
||||
value: '2',
|
||||
},
|
||||
{
|
||||
name: '玉米',
|
||||
value: '3',
|
||||
},
|
||||
]);
|
||||
const current = reactive({
|
||||
index: 0,
|
||||
length: list.value.length - 1,
|
||||
info: {
|
||||
name: '茶叶',
|
||||
value: '20',
|
||||
},
|
||||
});
|
||||
function handleChange(n) {
|
||||
if (current.index == 0 && n == -1) {
|
||||
current.index = current.length;
|
||||
} else if (current.index == current.length && n == 1) {
|
||||
current.index = 0;
|
||||
} else {
|
||||
current.index += n;
|
||||
}
|
||||
current.info = list.value[current.index];
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.hot-charts {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
._top_btns {
|
||||
position: relative;
|
||||
height: 40px;
|
||||
width: 30%;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
line-height: 40px;
|
||||
background: url('../../../assets/images/basic/tagBG-small.png') no-repeat center center / cover;
|
||||
span {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
text-shadow: 2px 0px 10px 0px #01eeff;
|
||||
}
|
||||
.left_btn {
|
||||
left: -10px;
|
||||
background: url('../../../assets/images/basic/leftArrowIcon.png') no-repeat center center / cover;
|
||||
}
|
||||
.right_btn {
|
||||
right: -10px;
|
||||
background: url('../../../assets/images/basic/rightArrowIcon.png') no-repeat center center / cover;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -2,9 +2,29 @@
|
||||
<el-row class="data-home-index">
|
||||
<el-col :span="6" class="left-charts">
|
||||
<div class="left-charts-item">
|
||||
<customBack top-title="全县历年产值对比" :top-postion="'left'">
|
||||
<customBack
|
||||
top-title="全县历年产值对比"
|
||||
:top-postion="'left'"
|
||||
:down-title="'全县'"
|
||||
:label-field="'label'"
|
||||
:value-field="'value'"
|
||||
:down-width="''"
|
||||
:options="[
|
||||
{ label: '全县', value: '530926' },
|
||||
{ label: '耿马镇', value: '42611' },
|
||||
{ label: '勐撒镇', value: '9259' },
|
||||
{ label: '勐永镇', value: '17787' },
|
||||
{ label: '孟定镇', value: '42610' },
|
||||
{ label: '勐简乡', value: '17788' },
|
||||
{ label: '贺派乡', value: '40161' },
|
||||
{ label: '四排山乡', value: '40163' },
|
||||
{ label: '大兴乡', value: '40159' },
|
||||
]"
|
||||
:is-down="true"
|
||||
@command="handleCommand"
|
||||
>
|
||||
<template #back>
|
||||
<entitiesCategoryCharts></entitiesCategoryCharts>
|
||||
<entitiesCategoryCharts ref="oneRef" :data="state.data.one" :query="state.queryCode"></entitiesCategoryCharts>
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
@ -16,9 +36,25 @@
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="left-charts-item">
|
||||
<customBack top-title="全县作物产量对比" :top-postion="'left'">
|
||||
<customBack
|
||||
top-title="全县作物产量对比"
|
||||
:top-postion="'left'"
|
||||
:down-title="'烟草'"
|
||||
:label-field="'label'"
|
||||
:value-field="'value'"
|
||||
:down-width="''"
|
||||
:options="[
|
||||
{ label: '烟草', value: 1 },
|
||||
{ label: '甘蔗', value: 2 },
|
||||
{ label: '核桃', value: 3 },
|
||||
{ label: '蔬菜', value: 4 },
|
||||
{ label: '其他', value: 5 },
|
||||
]"
|
||||
:is-down="true"
|
||||
@command="handleContrast"
|
||||
>
|
||||
<template #back>
|
||||
<entitiesStatistics></entitiesStatistics>
|
||||
<entitiesStatistics ref="thirdRef" :data="state.data.third" :query="state.contrastCode"></entitiesStatistics>
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
@ -52,6 +88,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
<script setup>
|
||||
import { nextTick, reactive, ref } from 'vue';
|
||||
import centerMap from '@/components/centerMap.vue';
|
||||
import categoryCharts from './components/categoryCharts.vue';
|
||||
import entitieslist from './components/entitieslist.vue';
|
||||
@ -60,6 +97,58 @@ import benefitCharts from './components/benefitCharts.vue';
|
||||
import entitiesStatistics from './components/entitiesStatistics.vue';
|
||||
import entitiesCategoryCharts from './components/entitiesCategoryCharts.vue';
|
||||
import entitiesMap from './components/entitiesMap.vue';
|
||||
import { sleep } from '@/utils';
|
||||
|
||||
const oneRef = ref(null);
|
||||
const thirdRef = ref(null);
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
data: {},
|
||||
queryCode: '',
|
||||
contrastCode: '',
|
||||
});
|
||||
const loadData = async () => {
|
||||
state.loading = true;
|
||||
await sleep(500);
|
||||
state.data = {
|
||||
one: [
|
||||
{ value: 5, name: '2020' },
|
||||
{ value: 36, name: '2021' },
|
||||
{ value: 70, name: '2022' },
|
||||
{ value: 56, name: '2023' },
|
||||
{ value: 70, name: '2024' },
|
||||
{ value: 20, name: '2025' },
|
||||
],
|
||||
third: [
|
||||
{ value: 98, value1: 88, name: '耿马镇' },
|
||||
{ value: 55, value1: 117, name: '勐撒镇' },
|
||||
{ value: 65, value1: 145, name: '勐永镇' },
|
||||
{ value: 60, value1: 126, name: '孟定镇' },
|
||||
{ value: 40, value1: 86, name: '勐简乡' },
|
||||
{ value: 81, value1: 152, name: '贺派乡' },
|
||||
{ value: 41, value1: 130, name: '四排山乡' },
|
||||
{ value: 100, value1: 101, name: '芒洪乡' },
|
||||
{ value: 79, value1: 184, name: '大兴乡' },
|
||||
],
|
||||
};
|
||||
};
|
||||
loadData();
|
||||
|
||||
const handleCommand = (data) => {
|
||||
state.queryCode = data.value;
|
||||
// console.info('data=', data);
|
||||
// nextTick(() => {
|
||||
// oneRef.value && oneRef.value.refresData();
|
||||
// });
|
||||
};
|
||||
const handleContrast = (data) => {
|
||||
state.contrastCode = data.value;
|
||||
// console.info('data=', data);
|
||||
nextTick(() => {
|
||||
thirdRef.value && thirdRef.value.refresData();
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.data-home-index {
|
||||
|
@ -2,8 +2,8 @@
|
||||
<div class="data-home-index">
|
||||
<template v-for="(n, index) in homeList" :key="n.name">
|
||||
<div class="home-enter-item" :style="n.style" @click="itemClick(index)">
|
||||
<div class="name">
|
||||
<span>{{ n.title || '--' }}</span>
|
||||
<div class="name" :style="n.nameStyle">
|
||||
<span :style="n.spanStyle">{{ n.title || '--' }}</span>
|
||||
</div>
|
||||
<div class="img-icon" :style="n.imgstyle"><img :src="getAssetsFile(n.img)" /></div>
|
||||
</div>
|
||||
@ -32,17 +32,21 @@ let homeList = reactive([
|
||||
linkType: 0,
|
||||
url: '',
|
||||
img: 'images/vsualized/home1.png',
|
||||
style: 'left: 20%;bottom:320px;',
|
||||
style: 'left: 21%;bottom:300px;',
|
||||
imgstyle: 'width:100px;height:100px',
|
||||
nameStyle: 'padding: 0 16px;margin: 16px 0;',
|
||||
spanStyle: 'font-size: 20px;',
|
||||
},
|
||||
{
|
||||
title: '农业产业运营服务平台',
|
||||
title: '产业运营平台',
|
||||
name: 'operation',
|
||||
linkType: 0,
|
||||
url: '',
|
||||
img: 'images/vsualized/home2.png',
|
||||
style: 'left: 20%;bottom: 64px;',
|
||||
style: 'left: 22%;bottom: 24px;',
|
||||
imgstyle: 'width:160px;height:160px',
|
||||
nameStyle: 'padding: 0 22px;margin: 24px 0;border-radius: 16px;',
|
||||
spanStyle: 'font-size: 28px;line-height: 66px',
|
||||
},
|
||||
{
|
||||
title: '数字大屏',
|
||||
@ -50,17 +54,21 @@ let homeList = reactive([
|
||||
linkType: 1,
|
||||
url: '/new-digital-agriculture-screen/v2/land',
|
||||
img: 'images/vsualized/home3.png',
|
||||
style: 'right: 20%;bottom:320px;',
|
||||
style: 'right: 23%;bottom:300px;',
|
||||
imgstyle: 'width:100px;height:100px',
|
||||
nameStyle: 'padding: 0 16px;margin: 16px 0;',
|
||||
spanStyle: 'font-size: 20px;',
|
||||
},
|
||||
{
|
||||
title: '农业产业政务服务平台',
|
||||
title: '政务云平台',
|
||||
name: 'gov',
|
||||
linkType: 0,
|
||||
url: '',
|
||||
img: 'images/vsualized/home4.png',
|
||||
style: 'right: 20%;bottom: 64px;',
|
||||
style: 'right: 24%;bottom: 24px;',
|
||||
imgstyle: 'width:160px;height:160px',
|
||||
nameStyle: 'padding: 0 22px;margin: 24px 0;border-radius: 16px;',
|
||||
spanStyle: 'font-size: 28px;line-height: 66px',
|
||||
},
|
||||
// 更多项...
|
||||
]);
|
||||
@ -107,17 +115,24 @@ const itemClick = (index) => {
|
||||
.name {
|
||||
color: #fff;
|
||||
font-family: 'JinBuTi';
|
||||
margin: 24px 0;
|
||||
background: linear-gradient(180deg, #01fefd, rgba(1, 254, 253, 0));
|
||||
border: 2px solid #01fefd;
|
||||
border-radius: 8px;
|
||||
|
||||
padding: 0 24px;
|
||||
span {
|
||||
backdrop-filter: blur(8px);
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(180deg, #01fefd, rgba(1, 254, 253, 0));
|
||||
opacity: 0.16; // 仅背景透明
|
||||
z-index: -1; // 将背景置于底层
|
||||
border-radius: 6px; // 比主元素小,避免覆盖边框
|
||||
}
|
||||
span {
|
||||
line-height: 40px;
|
||||
text-shadow: 0px 4px 8px 0px #01fefd;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
.img-icon {
|
||||
|
@ -23,20 +23,22 @@ const state = reactive({
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
className: 'custom-tooltip-container',
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||
backgroundColor: 'rgba(0,0,0,0.6);',
|
||||
borderColor: '#35d0c0',
|
||||
formatter: (data) => {
|
||||
const params = data[0];
|
||||
let str = `<div class="custom-echarts-tips">
|
||||
let str = `<div class="custom-echarts-tips" >
|
||||
<span>${params.name}</span><br/>
|
||||
<span>${params.marker} ${params.data} 万元</span>
|
||||
<span>${params.marker} ${params.data} 万亩</span>
|
||||
</div>`;
|
||||
return str;
|
||||
},
|
||||
extraCssText: 'backdrop-filter: blur(8px);',
|
||||
},
|
||||
barStyle: {
|
||||
barWidth: 14,
|
||||
@ -46,13 +48,13 @@ const state = reactive({
|
||||
},
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
x: 1,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
y2: 0,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#35D0C0' },
|
||||
{ offset: 1, color: '#35D0C0' },
|
||||
{ offset: 1, color: 'rgba(53,208,192,0)' },
|
||||
],
|
||||
global: false,
|
||||
},
|
||||
|
@ -128,16 +128,15 @@ const _circleNum = computed(() => {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
&.active {
|
||||
background-color: rgba($color: #4aeb82, $alpha: 0.4);
|
||||
border: 1px solid rgba($color: #008f32, $alpha: 08);
|
||||
background: rgba(38, 122, 102, 0.3);
|
||||
border: 1px solid #35d0c0;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
.spot {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
._label,
|
||||
._value {
|
||||
font-size: 18px;
|
||||
._label {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
._label {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<centerMap :dialog-title="'土地类型'" @mapclick="doMapclick">
|
||||
<centerMap class="land-map-body" :dialog-title="'土地类型'" @mapclick="doMapclick">
|
||||
<template #header>
|
||||
<div class="land-map-pop-header">
|
||||
<div class="title">土地类型</div>
|
||||
@ -49,6 +49,11 @@ const all = computed(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.land-map-body {
|
||||
:deep(.el-dialog__body) {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
.land-map-pop-header {
|
||||
display: inline-flex;
|
||||
justify-content: space-between;
|
||||
|
@ -22,25 +22,27 @@ const state = reactive({
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||
backgroundColor: 'rgba(0,0,0,0.5);',
|
||||
borderColor: '#35d0c0',
|
||||
formatter: (data) => {
|
||||
const params = data[0];
|
||||
let str = `<div class="custom-echarts-tips">
|
||||
let str = `<div class="custom-echarts-tips" >
|
||||
<span>${params.name}</span><br/>
|
||||
<span>${params.marker} ${params.data} 万亩</span>
|
||||
</div>`;
|
||||
return str;
|
||||
},
|
||||
extraCssText: 'backdrop-filter: blur(8px);',
|
||||
},
|
||||
barStyle: {
|
||||
barWidth: 15,
|
||||
barWidth: 16,
|
||||
itemStyle: {
|
||||
borderRadius: [8, 8, 0, 0], // 设置柱子的圆角半径
|
||||
borderRadius: 8, // 设置柱子的圆角半径
|
||||
},
|
||||
color: {
|
||||
type: 'linear',
|
||||
@ -49,23 +51,14 @@ const state = reactive({
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#35D0C0' },
|
||||
{ offset: 1, color: '#35D0C0' },
|
||||
{ offset: 0, color: '#35d0c0' },
|
||||
{ offset: 1, color: 'rgba(53,208,192,0)' },
|
||||
],
|
||||
global: false,
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
// name: '面积',
|
||||
// splitLine: {
|
||||
// show: false,
|
||||
// lineStyle: {
|
||||
// type: 'dashed',
|
||||
// color: '',
|
||||
// width: 1,
|
||||
// },
|
||||
// },
|
||||
axisTick: {
|
||||
show: false,
|
||||
alignWithLabel: false,
|
||||
@ -78,44 +71,11 @@ const state = reactive({
|
||||
color: 'rgba(28, 158, 222, 1)',
|
||||
},
|
||||
},
|
||||
// axisLine: {
|
||||
// show: true,
|
||||
// lineStyle: {
|
||||
// type: 'solid',
|
||||
// width: 1,
|
||||
// // color: '#000',
|
||||
// },
|
||||
// },
|
||||
// axisLabel: {
|
||||
// margin: 8,
|
||||
// interval: 'auto',
|
||||
// rotate: 0,
|
||||
// fontSize: 10,
|
||||
// color: '#fff',
|
||||
// },
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
// name: '面积(万亩)',
|
||||
},
|
||||
// label: {
|
||||
// show: true,
|
||||
// position: 'insideTop',
|
||||
// distance: -10,
|
||||
// formatter: () => {
|
||||
// return `{z|}{a|}`;
|
||||
// },
|
||||
// rich: {
|
||||
// a: {
|
||||
// widht: 18,
|
||||
// height: 18,
|
||||
// backgroundColor: {
|
||||
// image:
|
||||
// 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAARCAYAAADUryzEAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAKUSURBVHgBpVPPaxNBFH4zszubTTY2sSRSrFCC1dIepChoD9JgKwiem6s3vYl4lyb/QS/+wJPnBPQ/0LQ91KsHe5BaWo3Yupqk6WZ3Z3Z2xt2tKUUNHnww8OB775tv3nwP4D8DDQOqqoqh9iuPjlpeVkkxQurvBAoiREGlUcHbpUWcHaWkoGUivAWOPyUt5iiYgbABS/IkCTp5YxMAF1rTui36Rt70acipFmOEcqE8n+vaWZbf74jnl++KAQlOLlcKNZuA6X7JcPw9K2uSPOd68bY1NXtJL0zGeWiO5h3fsbxxk5abNRIrPlawVK8TmGtRx89ZJIVy93NzC9et0sMU6JMxzkF+XXc/1Fbab1+bmuq2RNcZ39jg9UojTBTkSx3spIu6oaHMLevC9E3r4tNBcxwU8NhCeurZg9y1GwRYJucX9e2lRYwi5TiW8nmEYe6FusIsfWfkyjIMiauZ0j2PozRJ92lxi2E1mAGcB8jwjoakQS1EZ4cRxBg1McUMkzNaFqEBgbeTTWYhlZChUs4wghCUw5gh43xnIv75mACBKkxkpKFbARiYtUNnbRhBW7hrUvicUCoK73flsQK7uSlZCgXI892X7uZjEU3992auwr1Xh++eEKr3fY8E9sx8YiiSyHlRhrFvPQT0NOyGP3puwDfO0XwuYseRf9mnoFtfOVx9tM6/fGShOPRhxy/ndsWbWvPI3rGRKtDAkWspQM8MkUpHtk6L0NIlOkAIpRhnro8Mo38Kep493guaUA3j5ydPiCpUAyrS3toMbEFcQke6ppWxteDAlszYV9L7zk9Bh4mWmzTXqlLB0Tr8uY3RTpQjWxcK09gx9hLcYm1l2/OyXF6VVVSViY0RKPhHHJGrpHTo2v8EGgI2uB3r9kQAAAAASUVORK5CYII=',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
},
|
||||
data: [],
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<custom-echart-hyaline-cake height="100%" :chart-data="state.data" :option="state.option" />
|
||||
<new-hyaline-cake height="100%" :chart-data="state.data" :option="state.option" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -15,23 +15,24 @@ const props = defineProps({
|
||||
|
||||
const state = reactive({
|
||||
option: {
|
||||
opacity: 0.6,
|
||||
itemGap: 0.2,
|
||||
k: 0.5,
|
||||
opacity: 1,
|
||||
itemGap: 0.1,
|
||||
legendSuffix: '万亩',
|
||||
itemHeight: 120,
|
||||
itemHeight: 200,
|
||||
grid3D: {
|
||||
show: false,
|
||||
boxHeight: 5,
|
||||
boxHeight: 1,
|
||||
top: '0',
|
||||
left: '-20%',
|
||||
viewControl: {
|
||||
//3d效果可以放大、旋转等,请自己去查看官方配置
|
||||
alpha: 30, //角度(这个很重要 调节角度的)
|
||||
distance: 260, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||
alpha: 45, //角度(这个很重要 调节角度的)
|
||||
distance: 300, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||
rotateSensitivity: 10, //设置旋转灵敏度,为0无法旋转
|
||||
zoomSensitivity: 10, //设置缩放灵敏度,为0无法缩放
|
||||
panSensitivity: 10, //设置平移灵敏度,0无法平移
|
||||
autoRotate: true, //自动旋转
|
||||
autoRotate: false, //自动旋转
|
||||
autoRotateAfterStill: 2, //在鼠标静止操作后恢复自动旋转的时间间隔,在开启 autoRotate 后有效
|
||||
},
|
||||
},
|
||||
|
@ -27,11 +27,12 @@ const state = reactive({
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
className: 'custom-tooltip-container',
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||
backgroundColor: 'rgba(0,0,0,0.6);',
|
||||
borderColor: '#35d0c0',
|
||||
formatter: (data) => {
|
||||
const params = data[0];
|
||||
@ -41,6 +42,7 @@ const state = reactive({
|
||||
</div>`;
|
||||
return str;
|
||||
},
|
||||
extraCssText: 'backdrop-filter: blur(8px);',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
@ -60,7 +62,6 @@ const state = reactive({
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
// name: '',
|
||||
},
|
||||
},
|
||||
data: [],
|
||||
|
@ -20,10 +20,10 @@ const state = reactive({
|
||||
option: {
|
||||
// 数据
|
||||
dataset: [],
|
||||
type: 'column',
|
||||
type: 'row',
|
||||
rowNum: 6,
|
||||
isAnimation: true,
|
||||
waitTime: 5,
|
||||
waitTime: 2,
|
||||
unit: '万元',
|
||||
sort: true,
|
||||
height: 12,
|
||||
@ -32,9 +32,9 @@ const state = reactive({
|
||||
borderRadius: '12px',
|
||||
carousel: 'single',
|
||||
indexPrefix: 'TOP',
|
||||
indexFontSize: 12,
|
||||
leftFontSize: 14,
|
||||
rightFontSize: 14,
|
||||
indexFontSize: 20,
|
||||
leftFontSize: 16,
|
||||
rightFontSize: 16,
|
||||
valueFormatter: (item) => {
|
||||
return item.value;
|
||||
},
|
||||
@ -61,8 +61,11 @@ watch(
|
||||
&:deep(.row-item) {
|
||||
.ranking-info {
|
||||
color: #35d0c0 !important;
|
||||
font-family: 'DingTalk JinBuTi, DingTalk JinBuTi-Regular';
|
||||
font-weight: 700;
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
.ranking-value {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.inside-column {
|
||||
|
344
new-digital-agriculture-screen/src/views/land/components/lsh.txt
Normal file
344
new-digital-agriculture-screen/src/views/land/components/lsh.txt
Normal file
@ -0,0 +1,344 @@
|
||||
let selectedIndex = '';
|
||||
let hoveredIndex = '';
|
||||
option = getPie3D(
|
||||
[
|
||||
{
|
||||
name: 'cc',
|
||||
value: 47,
|
||||
itemStyle: {
|
||||
color: '#f77b66',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'aa',
|
||||
value: 44,
|
||||
itemStyle: {
|
||||
color: '#3edce0',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'bb',
|
||||
value: 32,
|
||||
itemStyle: {
|
||||
color: '#f94e76',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'ee',
|
||||
value: 16,
|
||||
itemStyle: {
|
||||
color: '#018ef1',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'dd',
|
||||
value: 23,
|
||||
itemStyle: {
|
||||
color: '#9e60f9',
|
||||
},
|
||||
},
|
||||
],
|
||||
0.59
|
||||
);
|
||||
// 生成扇形的曲面参数方程
|
||||
function getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
|
||||
// 计算
|
||||
const midRatio = (startRatio + endRatio) / 2;
|
||||
|
||||
const startRadian = startRatio * Math.PI * 2;
|
||||
const endRadian = endRatio * Math.PI * 2;
|
||||
const midRadian = midRatio * Math.PI * 2;
|
||||
|
||||
// 如果只有一个扇形,则不实现选中效果。
|
||||
if (startRatio === 0 && endRatio === 1) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
isSelected = false;
|
||||
}
|
||||
|
||||
// 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
k = typeof k !== 'undefined' ? k : 1 / 3;
|
||||
|
||||
// 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
|
||||
const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
|
||||
const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
|
||||
|
||||
// 计算高亮效果的放大比例(未高亮,则比例为 1)
|
||||
const 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(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(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(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;
|
||||
}
|
||||
// 当前图形的高度是Z根据h(每个value的值决定的)
|
||||
return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
|
||||
},
|
||||
};
|
||||
}
|
||||
// 生成模拟 3D 饼图的配置项
|
||||
function getPie3D(pieData, internalDiameterRatio) {
|
||||
const series = [];
|
||||
// 总和
|
||||
let sumValue = 0;
|
||||
let startValue = 0;
|
||||
let endValue = 0;
|
||||
const legendData = [];
|
||||
const k =
|
||||
typeof internalDiameterRatio !== 'undefined'
|
||||
? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
|
||||
: 1 / 3;
|
||||
|
||||
// 为每一个饼图数据,生成一个 series-surface 配置
|
||||
for (let i = 0; i < pieData.length; i += 1) {
|
||||
sumValue += pieData[i].value;
|
||||
|
||||
const 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,
|
||||
},
|
||||
};
|
||||
|
||||
if (typeof pieData[i].itemStyle !== 'undefined') {
|
||||
const { itemStyle } = pieData[i];
|
||||
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
typeof pieData[i].itemStyle.color !== 'undefined' ? (itemStyle.color = pieData[i].itemStyle.color) : null;
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
typeof pieData[i].itemStyle.opacity !== 'undefined'
|
||||
? (itemStyle.opacity = pieData[i].itemStyle.opacity)
|
||||
: null;
|
||||
|
||||
seriesItem.itemStyle = itemStyle;
|
||||
}
|
||||
series.push(seriesItem);
|
||||
}
|
||||
// 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
|
||||
// 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
|
||||
console.log(series);
|
||||
for (let i = 0; i < series.length; i += 1) {
|
||||
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,
|
||||
false,
|
||||
false,
|
||||
k,
|
||||
// 我这里做了一个处理,使除了第一个之外的值都是10
|
||||
series[i].pieData.value === series[0].pieData.value ? 35 : 10
|
||||
);
|
||||
|
||||
startValue = endValue;
|
||||
|
||||
legendData.push(series[i].name);
|
||||
}
|
||||
|
||||
// 准备待返回的配置项,把准备好的 legendData、series 传入。
|
||||
const option = {
|
||||
// animation: false,
|
||||
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}`;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
xAxis3D: {
|
||||
min: -1,
|
||||
max: 1,
|
||||
},
|
||||
yAxis3D: {
|
||||
min: -1,
|
||||
max: 1,
|
||||
},
|
||||
zAxis3D: {
|
||||
min: -1,
|
||||
max: 1,
|
||||
},
|
||||
grid3D: {
|
||||
show: false,
|
||||
boxHeight: 5,
|
||||
top: '-20%',
|
||||
viewControl: {
|
||||
// 3d效果可以放大、旋转等,请自己去查看官方配置
|
||||
alpha: 35,
|
||||
// beta: 30,
|
||||
rotateSensitivity: 1,
|
||||
zoomSensitivity: 0,
|
||||
panSensitivity: 0,
|
||||
autoRotate: true,
|
||||
distance: 150,
|
||||
},
|
||||
// 后处理特效可以为画面添加高光、景深、环境光遮蔽(SSAO)、调色等效果。可以让整个画面更富有质感。
|
||||
postEffect: {
|
||||
// 配置这项会出现锯齿,请自己去查看官方配置有办法解决
|
||||
enable: false,
|
||||
bloom: {
|
||||
enable: true,
|
||||
bloomIntensity: 0.1,
|
||||
},
|
||||
SSAO: {
|
||||
enable: true,
|
||||
quality: 'medium',
|
||||
radius: 2,
|
||||
},
|
||||
// temporalSuperSampling: {
|
||||
// enable: true,
|
||||
// },
|
||||
},
|
||||
},
|
||||
series,
|
||||
};
|
||||
return option;
|
||||
}
|
||||
// 修正取消高亮失败的 bug
|
||||
// 监听 mouseover,近似实现高亮(放大)效果
|
||||
myChart.on('mouseover', function (params) {
|
||||
// 准备重新渲染扇形所需的参数
|
||||
let isSelected;
|
||||
let isHovered;
|
||||
let startRatio;
|
||||
let endRatio;
|
||||
let k;
|
||||
let i;
|
||||
|
||||
// 如果触发 mouseover 的扇形当前已高亮,则不做操作
|
||||
if (hoveredIndex === params.seriesIndex) {
|
||||
return;
|
||||
|
||||
// 否则进行高亮及必要的取消高亮操作
|
||||
} else {
|
||||
// 如果当前有高亮的扇形,取消其高亮状态(对 option 更新)
|
||||
if (hoveredIndex !== '') {
|
||||
// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 false。
|
||||
isSelected = option.series[hoveredIndex].pieStatus.selected;
|
||||
isHovered = false;
|
||||
startRatio = option.series[hoveredIndex].pieData.startRatio;
|
||||
endRatio = option.series[hoveredIndex].pieData.endRatio;
|
||||
k = option.series[hoveredIndex].pieStatus.k;
|
||||
i = option.series[hoveredIndex].pieData.value === option.series[0].pieData.value ? 35 : 10;
|
||||
// 对当前点击的扇形,执行取消高亮操作(对 option 更新)
|
||||
option.series[hoveredIndex].parametricEquation = getParametricEquation(
|
||||
startRatio,
|
||||
endRatio,
|
||||
isSelected,
|
||||
isHovered,
|
||||
k,
|
||||
i
|
||||
);
|
||||
option.series[hoveredIndex].pieStatus.hovered = isHovered;
|
||||
|
||||
// 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空
|
||||
hoveredIndex = '';
|
||||
}
|
||||
|
||||
// 如果触发 mouseover 的扇形不是透明圆环,将其高亮(对 option 更新)
|
||||
if (params.seriesName !== 'mouseoutSeries') {
|
||||
// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。
|
||||
isSelected = option.series[params.seriesIndex].pieStatus.selected;
|
||||
isHovered = true;
|
||||
startRatio = option.series[params.seriesIndex].pieData.startRatio;
|
||||
endRatio = option.series[params.seriesIndex].pieData.endRatio;
|
||||
k = option.series[params.seriesIndex].pieStatus.k;
|
||||
|
||||
// 对当前点击的扇形,执行高亮操作(对 option 更新)
|
||||
option.series[params.seriesIndex].parametricEquation = getParametricEquation(
|
||||
startRatio,
|
||||
endRatio,
|
||||
isSelected,
|
||||
isHovered,
|
||||
k,
|
||||
option.series[params.seriesIndex].pieData.value + 5
|
||||
);
|
||||
option.series[params.seriesIndex].pieStatus.hovered = isHovered;
|
||||
|
||||
// 记录上次高亮的扇形对应的系列号 seriesIndex
|
||||
hoveredIndex = params.seriesIndex;
|
||||
}
|
||||
|
||||
// 使用更新后的 option,渲染图表
|
||||
myChart.setOption(option);
|
||||
}
|
||||
});
|
||||
|
||||
// 修正取消高亮失败的 bug
|
||||
myChart.on('globalout', function () {
|
||||
if (hoveredIndex !== '') {
|
||||
// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。
|
||||
isSelected = option.series[hoveredIndex].pieStatus.selected;
|
||||
isHovered = false;
|
||||
k = option.series[hoveredIndex].pieStatus.k;
|
||||
startRatio = option.series[hoveredIndex].pieData.startRatio;
|
||||
endRatio = option.series[hoveredIndex].pieData.endRatio;
|
||||
// 对当前点击的扇形,执行取消高亮操作(对 option 更新)
|
||||
i = option.series[hoveredIndex].pieData.value === option.series[0].pieData.value ? 35 : 10;
|
||||
option.series[hoveredIndex].parametricEquation = getParametricEquation(
|
||||
startRatio,
|
||||
endRatio,
|
||||
isSelected,
|
||||
isHovered,
|
||||
k,
|
||||
i
|
||||
);
|
||||
option.series[hoveredIndex].pieStatus.hovered = isHovered;
|
||||
|
||||
// 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空
|
||||
hoveredIndex = '';
|
||||
}
|
||||
|
||||
// 使用更新后的 option,渲染图表
|
||||
myChart.setOption(option);
|
||||
});
|
@ -9,7 +9,7 @@
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="left-charts-item">
|
||||
<customBack top-title="农村土地资源项目效益" :top-postion="'left'">
|
||||
<customBack top-title="农村土地资源" :top-postion="'left'">
|
||||
<template #back>
|
||||
<landTwo :data="state.data.two" />
|
||||
</template>
|
||||
@ -55,14 +55,31 @@
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="right-charts-item">
|
||||
<customBack top-title="年度农用地规划面积" :top-postion="'right'">
|
||||
<customBack
|
||||
top-title="管理需求分类"
|
||||
:down-title="'永久基本农田'"
|
||||
:top-postion="'right'"
|
||||
:down-width="'140px'"
|
||||
:options="[
|
||||
{ label: '永久基本农田', value: '530926' },
|
||||
{ label: '耿马镇', value: '42611' },
|
||||
{ label: '勐撒镇', value: '9259' },
|
||||
{ label: '勐永镇', value: '17787' },
|
||||
{ label: '孟定镇', value: '42610' },
|
||||
{ label: '勐简乡', value: '17788' },
|
||||
{ label: '贺派乡', value: '40161' },
|
||||
{ label: '四排山乡', value: '40163' },
|
||||
{ label: '大兴乡', value: '40159' },
|
||||
]"
|
||||
:is-down="true"
|
||||
>
|
||||
<template #back>
|
||||
<landFive :data="state.data.five" />
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="right-charts-item">
|
||||
<customBack top-title="各地农用地利用面积" :top-postion="'right'">
|
||||
<customBack top-title="全县作物情况" :top-postion="'right'">
|
||||
<template #back>
|
||||
<landSix :data="state.data.six" />
|
||||
</template>
|
||||
@ -198,9 +215,22 @@ const handleCommand = (data) => {
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep(.custom-back-content) {
|
||||
padding: 8px !important; /* 强制覆盖 padding */
|
||||
}
|
||||
|
||||
.data-home-index {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: 'DingTalk JinBuTi, DingTalk JinBuTi-Regular';
|
||||
font-weight: 400;
|
||||
:deep(*) {
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
:deep(.title-top-content) {
|
||||
font-size: 24px;
|
||||
}
|
||||
.left-charts {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
@ -23,10 +23,7 @@ import { resolve } from 'path';
|
||||
const useDevMode = true;
|
||||
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
const { VITE_APP_MIAN_URL, VITE_PORT, VITE_APP_NAME, VITE_APP_BASE_API, VITE_APP_BASE_URL, VITE_APP_UPLOAD_API, VITE_APP_UPLOAD_URL } = loadEnv(
|
||||
mode,
|
||||
process.cwd()
|
||||
);
|
||||
const { VITE_APP_MIAN_URL, VITE_PORT, VITE_APP_NAME, VITE_APP_BASE_API, VITE_APP_BASE_URL, VITE_APP_UPLOAD_API, VITE_APP_UPLOAD_URL } = loadEnv(mode, process.cwd());
|
||||
const config = {
|
||||
base: '/new-digital-agriculture-screen/',
|
||||
build: {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,18 +8,18 @@ const annualplanRoutes = [
|
||||
redirect: '/sub-government-affairs-service/annualPlans',
|
||||
meta: { title: '年度种植计划', icon: '' },
|
||||
children: [
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/annualPlans',
|
||||
// name: 'annualPlans',
|
||||
// component: () => import('@/views/annualPlan/component/annualPlans/index.vue'),
|
||||
// meta: { title: '年度种植计划', icon: '' },
|
||||
// },
|
||||
{
|
||||
path: '/sub-government-affairs-service/annualPlans',
|
||||
name: 'annualPlans',
|
||||
component: () => import('@/views/annualPlan/component/annualPlans/index.vue'),
|
||||
meta: { title: '年度种植计划', icon: '' },
|
||||
meta: { title: '网格种植进度', icon: 'Memo' },
|
||||
},
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/plantings',
|
||||
// name: 'plantings',
|
||||
// component: () => import('@/views/annualPlan/component/plantings/index.vue'),
|
||||
// meta: { title: '网格种植进度', icon: 'Document' },
|
||||
// },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
@ -13,7 +13,7 @@ const dictRoutes = [
|
||||
path: '/sub-government-affairs-service/region',
|
||||
name: 'region',
|
||||
component: () => import('@/views/dict/component/region/index.vue'),
|
||||
meta: { title: '行政区域信息', icon: '' },
|
||||
meta: { title: '行政信息', icon: '' },
|
||||
},
|
||||
{
|
||||
path: '/sub-government-affairs-service/landCassification',
|
||||
@ -21,18 +21,18 @@ const dictRoutes = [
|
||||
component: () => import('@/views/dict/component/landCassification/index.vue'),
|
||||
meta: { title: '土地分类', icon: '' },
|
||||
},
|
||||
{
|
||||
path: '/sub-government-affairs-service/dictCrop',
|
||||
name: 'dictCrop',
|
||||
component: () => import('@/views/dict/component/dictCrop/index.vue'),
|
||||
meta: { title: '种植产物信息', icon: '' },
|
||||
},
|
||||
{
|
||||
path: '/sub-government-affairs-service/soilClassification',
|
||||
name: 'soilClassification',
|
||||
component: () => import('@/views/dict/component/soilClassification/index.vue'),
|
||||
meta: { title: '土壤分类', icon: '' },
|
||||
},
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/dictCrop',
|
||||
// name: 'dictCrop',
|
||||
// component: () => import('@/views/dict/component/dictCrop/index.vue'),
|
||||
// meta: { title: '种植产物信息', icon: '' },
|
||||
// },
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/soilClassification',
|
||||
// name: 'soilClassification',
|
||||
// component: () => import('@/views/dict/component/soilClassification/index.vue'),
|
||||
// meta: { title: '土壤分类', icon: '' },
|
||||
// },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
@ -38,7 +38,7 @@ const inputSuppliesRoutes = [
|
||||
path: '/sub-government-affairs-service/material/pesticide',
|
||||
name: 'input-supplies-pesticide',
|
||||
component: () => import('@/views/inputSuppliesManage/material/pesticide/index.vue'),
|
||||
meta: { title: '农药管理', icon: 'Document' },
|
||||
meta: { title: '农药管理', icon: '' },
|
||||
},
|
||||
{
|
||||
path: '/sub-government-affairs-service/material/ratPoison',
|
||||
@ -70,7 +70,7 @@ const inputSuppliesRoutes = [
|
||||
path: '/sub-government-affairs-service/enterpriseDealerCheck',
|
||||
name: 'enterpriseDealerCheck',
|
||||
component: () => import('@/views/inputSuppliesManage/enterpriseDealerCheck/index.vue'),
|
||||
meta: { title: '企业经销商抽检', icon: 'Document' },
|
||||
meta: { title: '企业经销商抽检', icon: '' },
|
||||
},
|
||||
{
|
||||
path: '/sub-government-affairs-service/useSupervise',
|
||||
|
@ -6,20 +6,20 @@ const landsRoutes = [
|
||||
path: '/sub-government-affairs-service/landManage',
|
||||
name: 'landManage',
|
||||
component: Views,
|
||||
redirect: '/sub-government-affairs-service/landsManage',
|
||||
redirect: '/sub-government-affairs-service/plantPlan',
|
||||
meta: { title: '土地管理', icon: 'Grape' },
|
||||
children: [
|
||||
{
|
||||
path: '/sub-government-affairs-service/landsManage',
|
||||
name: 'landsManage',
|
||||
component: () => import('@/views/landManage/component/landsManage/index.vue'),
|
||||
meta: { title: '土地信息登记', icon: '' },
|
||||
},
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/landsManage',
|
||||
// name: 'landsManage',
|
||||
// component: () => import('@/views/landManage/component/landsManage/index.vue'),
|
||||
// meta: { title: '土地信息登记', icon: '' },
|
||||
// },
|
||||
{
|
||||
path: '/sub-government-affairs-service/plantPlan',
|
||||
name: 'plantPlan',
|
||||
component: () => import('@/views/landManage/component/plantPlan/index.vue'),
|
||||
meta: { title: '种植规划', icon: '' },
|
||||
meta: { title: '种植计划', icon: '' },
|
||||
},
|
||||
{
|
||||
path: '/sub-government-affairs-service/operationRecord',
|
||||
|
@ -13,10 +13,25 @@ export default [
|
||||
meta: { title: '土地资源管理', icon: 'icon-test' },
|
||||
children: [
|
||||
{
|
||||
redirect: '/sub-government-affairs-service/grid',
|
||||
path: '/sub-government-affairs-service/grid',
|
||||
component: () => import('@/views/resource/grid/index.vue'),
|
||||
name: 'grid',
|
||||
meta: { title: '网格化管理', icon: '' },
|
||||
meta: { title: '网格化管理', icon: 'Memo' },
|
||||
children: [
|
||||
{
|
||||
path: '/sub-government-affairs-service/grid',
|
||||
component: () => import('@/views/resource/grid/index.vue'),
|
||||
name: 'grid1',
|
||||
meta: { title: '新增网格', icon: '' },
|
||||
},
|
||||
{
|
||||
path: '/sub-government-affairs-service/grid',
|
||||
component: () => import('@/views/resource/grid/index.vue'),
|
||||
name: 'grid2',
|
||||
meta: { title: '网格化地图', icon: '' },
|
||||
},
|
||||
],
|
||||
},
|
||||
...annualplanRouters,
|
||||
...landsRoutes,
|
||||
|
@ -30,26 +30,26 @@ export default [
|
||||
path: '/sub-government-affairs-service/system-dept',
|
||||
component: () => import('@/views/system/dept/index.vue'),
|
||||
name: 'system-dept',
|
||||
meta: { title: '部门管理', icon: 'Document' },
|
||||
meta: { title: '部门管理', icon: '' },
|
||||
},
|
||||
{
|
||||
path: '/sub-government-affairs-service/system-role',
|
||||
component: () => import('@/views/system/role/index.vue'),
|
||||
name: 'system-role',
|
||||
meta: { title: '角色管理', icon: 'Document' },
|
||||
meta: { title: '角色管理', icon: '' },
|
||||
},
|
||||
{
|
||||
path: '/sub-government-affairs-service/system-auth-user',
|
||||
component: () => import('@/views/system/role/authUser.vue'),
|
||||
name: 'system-auth-user',
|
||||
meta: { title: '分配用户', icon: 'Document' },
|
||||
meta: { title: '分配用户', icon: '' },
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
path: '/sub-government-affairs-service/system-user',
|
||||
component: () => import('@/views/system/user/index.vue'),
|
||||
name: 'system-user',
|
||||
meta: { title: '用户管理', icon: 'Document' },
|
||||
meta: { title: '用户管理', icon: '' },
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -57,7 +57,7 @@ publicAxios.interceptors.request.use(async (config) => {
|
||||
}
|
||||
|
||||
config.headers['authorization'] =
|
||||
'eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjozLCJ1c2VyX2tleSI6ImQxNGRhZjMzLWJkODQtNDc1Yy1iMDU3LWE5MmI2OTgyYmY1MyIsInVzZXJuYW1lIjoidGVzdCJ9.3AFekADq1-7-k_OAIQuJterJnVUVCK1rTSYg3X32UHhepBUO95fU-du9joJ_3ZepTrgBHvJApFTqP2x9041THQ';
|
||||
'eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VyX2tleSI6IjVlZmMzZTZlLWEwZTUtNDcxYi05YmU5LWI3NDcwNDQxYTUzMCIsInVzZXJuYW1lIjoiYWRtaW4ifQ.cIgRynK84hfjO6YfW206i3UajKRvIkLBmfYmENeVpbFfYc62gPz9gW8Y3JiU5j5s8KxfuxYqbFP16M5WIppXqw';
|
||||
if (UserStore.hasToken()) {
|
||||
config.headers['authorization'] = config.headers['authorization'] ?? UserStore.token;
|
||||
config.headers['cache-control'] = 'no-cache';
|
||||
|
Loading…
x
Reference in New Issue
Block a user