合并所有平台
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']
|
CustomScrollTitle: typeof import('./src/components/custom-scroll-title/index.vue')['default']
|
||||||
CustomTableOperate: typeof import('./src/components/custom-table-operate/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']
|
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']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
SubTop: typeof import('./src/components/subTop.vue')['default']
|
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": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.3.1",
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
"@smallwei/avue": "^3.6.2",
|
"@smallwei/avue": "^3.6.2",
|
||||||
|
"@vuemap/vue-amap": "^2.0",
|
||||||
|
"@vuemap/vue-amap-loca": "^2.0",
|
||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
@ -25,8 +27,6 @@
|
|||||||
"echarts-gl": "^2.0.9",
|
"echarts-gl": "^2.0.9",
|
||||||
"echarts-liquidfill": "^3.1.0",
|
"echarts-liquidfill": "^3.1.0",
|
||||||
"echarts-wordcloud": "^2.1.0",
|
"echarts-wordcloud": "^2.1.0",
|
||||||
"@vuemap/vue-amap": "^2.0",
|
|
||||||
"@vuemap/vue-amap-loca": "^2.0",
|
|
||||||
"element-plus": "^2.7.2",
|
"element-plus": "^2.7.2",
|
||||||
"js-base64": "^3.7.6",
|
"js-base64": "^3.7.6",
|
||||||
"lodash": "^4.17.21",
|
"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.series[1].data = yDataLine.value;
|
||||||
option.xAxis.data = xData.value;
|
option.xAxis.data = xData.value;
|
||||||
setOptions(option);
|
setOptions(option);
|
||||||
// startAutoPlay({
|
startAutoPlay({
|
||||||
// interval: 2000,
|
interval: 2000,
|
||||||
// seriesIndex: 0,
|
seriesIndex: 0,
|
||||||
// showTooltip: true,
|
showTooltip: true,
|
||||||
// });
|
});
|
||||||
getInstance()?.off('click', onClick);
|
getInstance()?.off('click', onClick);
|
||||||
getInstance()?.on('click', onClick);
|
getInstance()?.on('click', onClick);
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,9 @@ export default {
|
|||||||
const option = Object.assign(
|
const option = Object.assign(
|
||||||
{
|
{
|
||||||
tooltip: {
|
tooltip: {
|
||||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
// tooltip样式调整添加这个类名
|
||||||
|
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||||
borderColor: '#35d0c0',
|
borderColor: '#35d0c0',
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
position: function (point, params, dom, rect, size) {
|
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 { setOptions, getInstance, resize, startAutoPlay } = useEcharts(chartRef);
|
||||||
const option = reactive({
|
const option = reactive({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
// trigger: 'axis',
|
trigger: 'axis',
|
||||||
// axisPointer: {
|
axisPointer: {
|
||||||
// type: 'shadow',
|
type: 'shadow',
|
||||||
// },
|
},
|
||||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
||||||
borderColor: '#35d0c0',
|
borderColor: '#35d0c0',
|
||||||
formatter: (data) => {
|
formatter: (data) => {
|
||||||
@ -56,28 +56,62 @@ export default {
|
|||||||
zlevel: 1,
|
zlevel: 1,
|
||||||
name: '漏斗图',
|
name: '漏斗图',
|
||||||
type: 'funnel',
|
type: 'funnel',
|
||||||
|
top: '11%',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
width: '28%',
|
width: '25%',
|
||||||
sort: 'ascending',
|
sort: 'ascending',
|
||||||
gap: 0,
|
gap: 0,
|
||||||
label: {
|
label: {
|
||||||
show: true,
|
show: true,
|
||||||
position: 'right',
|
position: 'outside',
|
||||||
width: '200px',
|
width: '200px',
|
||||||
align: 'right',
|
align: 'right',
|
||||||
formatter: function (params) {
|
formatter: function (params) {
|
||||||
|
if (!params.data.reaVal) return '';
|
||||||
let arr = [`{a|${params.data.name}}`, `{b| ${params.data.reaVal}%}`];
|
let arr = [`{a|${params.data.name}}`, `{b| ${params.data.reaVal}%}`];
|
||||||
return arr.join('\n');
|
return arr.join('\n');
|
||||||
// params.data.name + ':' + params.data.reaVal + '%'};
|
|
||||||
},
|
},
|
||||||
rich: {
|
rich: {
|
||||||
a: { color: '#fff', fontSize: '16px' },
|
a: { color: '#fff', fontSize: '16px' },
|
||||||
b: { color: '#05FCC6', fontSize: '16px' },
|
b: { color: '#05FCC6', fontSize: '16px', marginTop: '10px' },
|
||||||
},
|
},
|
||||||
|
verticalAlign: 'middle',
|
||||||
|
padding: [5, 6], // 增加标签内边距
|
||||||
},
|
},
|
||||||
labelLine: {
|
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: {
|
itemStyle: {
|
||||||
show: false,
|
show: false,
|
||||||
borderColor: '#fff',
|
borderColor: '#fff',
|
||||||
|
@ -204,6 +204,7 @@ onUnmounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
flex: none;
|
||||||
.rank {
|
.rank {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
@ -212,7 +213,7 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.ranking-column {
|
.ranking-column {
|
||||||
width: 100%;
|
flex: 1;
|
||||||
.inside-column {
|
.inside-column {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -69,7 +69,7 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
const titleContentW = ref('0');
|
const titleContentW = ref('0');
|
||||||
const itemW = ref('1');
|
const itemW = ref('1');
|
||||||
const gap = ref(24);
|
const gap = ref(1);
|
||||||
const leftNum = ref(0);
|
const leftNum = ref(0);
|
||||||
const position = ref(0);
|
const position = ref(0);
|
||||||
const right = ref(null);
|
const right = ref(null);
|
||||||
@ -133,7 +133,7 @@ function handleTitleClick(val) {
|
|||||||
.header_title {
|
.header_title {
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0 68px;
|
padding: 0 40px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
@ -174,7 +174,7 @@ function handleTitleClick(val) {
|
|||||||
.left_titles_container,
|
.left_titles_container,
|
||||||
.right_titles_container {
|
.right_titles_container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 30%;
|
width: 31%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
line-height: 90px;
|
line-height: 90px;
|
||||||
@ -182,10 +182,10 @@ function handleTitleClick(val) {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
width: var(--titleContentW);
|
width: var(--titleContentW);
|
||||||
height: 40px;
|
height: 56px;
|
||||||
transition: all 0.4s ease;
|
transition: all 0.4s ease;
|
||||||
font-size: 20px;
|
font-size: 24px;
|
||||||
font-weight: bold;
|
// font-weight: bold;
|
||||||
.active {
|
.active {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
@ -194,9 +194,9 @@ function handleTitleClick(val) {
|
|||||||
.title_item {
|
.title_item {
|
||||||
margin-right: var(--gap);
|
margin-right: var(--gap);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: var(--itemW);
|
min-width: var(--itemW);
|
||||||
height: 40px;
|
height: 56px;
|
||||||
line-height: 40px;
|
line-height: 56px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #f5fffe;
|
color: #f5fffe;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
></div>
|
></div>
|
||||||
<span class="title-top-content" :style="{ 'text-align': props.left }">{{ topTitle || '--' }}</span>
|
<span class="title-top-content" :style="{ 'text-align': props.left }">{{ topTitle || '--' }}</span>
|
||||||
<div v-if="isDown" class="down-list" :style="{ width: downWidth }">
|
<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">
|
<span class="el-dropdown-link">
|
||||||
{{ currentVal && currentVal[labelField] ? currentVal[labelField] : downTitle }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
{{ currentVal && currentVal[labelField] ? currentVal[labelField] : downTitle }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
</span>
|
</span>
|
||||||
@ -147,15 +147,15 @@ const handleCommand = (data) => {
|
|||||||
}
|
}
|
||||||
.title-top-content {
|
.title-top-content {
|
||||||
line-height: 38px;
|
line-height: 38px;
|
||||||
font-size: 14px;
|
font-size: 20px;
|
||||||
font-weight: bold;
|
// font-weight: bold;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
transform: skewX(-13deg);
|
transform: skewX(-13deg);
|
||||||
background: linear-gradient(to bottom, '#ff7e5f', '#548fff');
|
background: linear-gradient(to bottom, '#ff7e5f', '#548fff');
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
letter-spacing: 4px;
|
letter-spacing: 4px;
|
||||||
text-shadow: -2px 0 0 1px #add8f1;
|
text-shadow: -2px 0 10px #add8f1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 36px 0 72px;
|
padding: 0 36px 0 72px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -167,7 +167,7 @@ const handleCommand = (data) => {
|
|||||||
.down-list {
|
.down-list {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 32px;
|
right: 0;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
@ -178,6 +178,8 @@ const handleCommand = (data) => {
|
|||||||
border: 1px solid $color-custom-main;
|
border: 1px solid $color-custom-main;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,9 @@ import echarts from '../utils/echarts';
|
|||||||
|
|
||||||
export const useEcharts = (elRef, theme = 'default') => {
|
export const useEcharts = (elRef, theme = 'default') => {
|
||||||
// 新增轮播相关状态
|
// 新增轮播相关状态
|
||||||
const autoPlayTimer = ref(null);
|
const autoPlayTimer = ref(null); // 定时器句柄
|
||||||
const currentIndex = ref(-1);
|
const currentIndex = ref(-1); // 当前高亮的数据索引
|
||||||
const dataLength = ref(0);
|
const dataLength = ref(0); // 当前系列的数据总长度
|
||||||
|
|
||||||
let mapClickHandler = null;
|
let mapClickHandler = null;
|
||||||
|
|
||||||
@ -18,29 +18,41 @@ export const useEcharts = (elRef, theme = 'default') => {
|
|||||||
const {
|
const {
|
||||||
interval = 2000, // 轮播间隔(ms)
|
interval = 2000, // 轮播间隔(ms)
|
||||||
seriesIndex = 0, // 默认操作第一个系列
|
seriesIndex = 0, // 默认操作第一个系列
|
||||||
showTooltip = true, // 是否显示提示框
|
showTooltip = false, // 是否显示提示框,默认是false,外部配置了,无论是否true都会显示
|
||||||
|
showMarkPoint = true, // 是否显示默认的动态标记点
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
stopAutoPlay(); // 先停止已有轮播
|
stopAutoPlay(); // 先停止已有轮播
|
||||||
|
|
||||||
// 获取数据长度
|
// 获取当前系列的数据长度
|
||||||
const seriesData = unref(getOptions).series?.[seriesIndex]?.data;
|
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;
|
dataLength.value = seriesData?.length || 0;
|
||||||
if (dataLength.value === 0) return;
|
if (dataLength.value === 0) return;
|
||||||
|
|
||||||
autoPlayTimer.value = setInterval(() => {
|
autoPlayTimer.value = setInterval(() => {
|
||||||
currentIndex.value = (currentIndex.value + 1) % dataLength.value;
|
currentIndex.value = (currentIndex.value + 1) % dataLength.value;
|
||||||
|
// 更新MarkPoint点信息
|
||||||
|
if (showMarkPoint) {
|
||||||
|
updateMarkPoint(currentIndex.value, xAxisData, seriesData, isCategoryY);
|
||||||
|
}
|
||||||
|
|
||||||
// 执行轮播动作
|
// 重置之前的高亮
|
||||||
chartInstance?.dispatchAction({
|
chartInstance?.dispatchAction({
|
||||||
type: 'downplay',
|
type: 'downplay',
|
||||||
seriesIndex: seriesIndex,
|
seriesIndex: seriesIndex,
|
||||||
});
|
});
|
||||||
|
// 高亮当前项
|
||||||
chartInstance?.dispatchAction({
|
chartInstance?.dispatchAction({
|
||||||
type: 'highlight',
|
type: 'highlight',
|
||||||
seriesIndex: seriesIndex,
|
seriesIndex: seriesIndex,
|
||||||
dataIndex: currentIndex.value,
|
dataIndex: currentIndex.value,
|
||||||
});
|
});
|
||||||
|
// 显示 tooltip(可选)
|
||||||
if (showTooltip) {
|
if (showTooltip) {
|
||||||
chartInstance?.dispatchAction({
|
chartInstance?.dispatchAction({
|
||||||
type: 'showTip',
|
type: 'showTip',
|
||||||
@ -51,6 +63,40 @@ export const useEcharts = (elRef, theme = 'default') => {
|
|||||||
}, interval);
|
}, 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 = () => {
|
const stopAutoPlay = () => {
|
||||||
if (autoPlayTimer.value) {
|
if (autoPlayTimer.value) {
|
||||||
|
@ -74,6 +74,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
.base-laytout-header {
|
.base-laytout-header {
|
||||||
height: 90px;
|
height: 90px;
|
||||||
|
margin-bottom: 50px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</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 {
|
.custom-echarts-tips {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,9 @@ import {
|
|||||||
CalendarComponent,
|
CalendarComponent,
|
||||||
GraphicComponent,
|
GraphicComponent,
|
||||||
GeoComponent,
|
GeoComponent,
|
||||||
|
MarkPointComponent,
|
||||||
|
MarkLineComponent,
|
||||||
|
MarkAreaComponent,
|
||||||
} from 'echarts/components';
|
} from 'echarts/components';
|
||||||
|
|
||||||
import { CanvasRenderer } from 'echarts/renderers';
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
@ -64,6 +67,9 @@ echarts.use([
|
|||||||
ScatterChart,
|
ScatterChart,
|
||||||
EffectScatterChart,
|
EffectScatterChart,
|
||||||
GeoComponent,
|
GeoComponent,
|
||||||
|
MarkPointComponent,
|
||||||
|
MarkLineComponent,
|
||||||
|
MarkAreaComponent,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export default echarts;
|
export default echarts;
|
||||||
|
@ -40,6 +40,7 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
|
next();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(`/login?redirect=${to.path}`);
|
next(`/login?redirect=${to.path}`);
|
||||||
|
@ -127,7 +127,7 @@ watch(
|
|||||||
width: 160px;
|
width: 160px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
line-height: 32px;
|
line-height: 26px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -199,7 +199,9 @@ function getPie3D(pieData, internalDiameterRatio) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
// tooltip样式调整添加这个类名
|
||||||
|
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||||
borderColor: '#35d0c0',
|
borderColor: '#35d0c0',
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
position: function (point, params, dom, rect, size) {
|
position: function (point, params, dom, rect, size) {
|
||||||
|
@ -27,7 +27,9 @@ const state = reactive({
|
|||||||
axisPointer: {
|
axisPointer: {
|
||||||
type: 'shadow',
|
type: 'shadow',
|
||||||
},
|
},
|
||||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
// tooltip样式调整添加这个类名
|
||||||
|
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||||
borderColor: '#35d0c0',
|
borderColor: '#35d0c0',
|
||||||
formatter: (data) => {
|
formatter: (data) => {
|
||||||
const params = data[0];
|
const params = data[0];
|
||||||
|
@ -30,7 +30,9 @@ const state = reactive({
|
|||||||
axisPointer: {
|
axisPointer: {
|
||||||
type: 'shadow',
|
type: 'shadow',
|
||||||
},
|
},
|
||||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
// tooltip样式调整添加这个类名
|
||||||
|
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||||
borderColor: '#35d0c0',
|
borderColor: '#35d0c0',
|
||||||
formatter: (data) => {
|
formatter: (data) => {
|
||||||
const params = data[0];
|
const params = data[0];
|
||||||
|
@ -145,6 +145,7 @@ function handleChange(n) {
|
|||||||
top: 8px;
|
top: 8px;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
text-shadow: 2px 0px 10px 0px #01eeff;
|
||||||
}
|
}
|
||||||
.left_btn {
|
.left_btn {
|
||||||
left: 6px;
|
left: 6px;
|
||||||
|
@ -1,39 +1,60 @@
|
|||||||
<template>
|
<template>
|
||||||
<customEchartHyalineCake :chart-data="data" height="100%" :option="option" />
|
<customEchartHyalineCake ref="chartRef" :chart-data="data" height="100%" :option="option" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref, onMounted } from 'vue';
|
||||||
|
const chartRef = ref(null);
|
||||||
|
|
||||||
/* --------------- data --------------- */
|
/* --------------- data右上侧饼图 --------------- */
|
||||||
// #region
|
// #region
|
||||||
const data = ref([
|
const data = ref([
|
||||||
{
|
{
|
||||||
name: '企业',
|
name: ' 企业',
|
||||||
value: 10.8,
|
value: 10.8,
|
||||||
|
itemStyle: { color: '#5b7bc7', opacity: 0.8 },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '合作社',
|
name: ' 合作社',
|
||||||
value: 8.4,
|
value: 18.4,
|
||||||
|
itemStyle: { color: '#8ed0f3', opacity: 0.8 },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '村集体',
|
name: ' 村集体',
|
||||||
value: 4.3,
|
value: 14.3,
|
||||||
|
itemStyle: { color: '#65be97', opacity: 0.8 },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '个体',
|
name: ' 个体',
|
||||||
value: 3.7,
|
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({
|
const option = reactive({
|
||||||
k: 0.2,
|
k: 0.2,
|
||||||
opacity: 0.6,
|
opacity: 0.4,
|
||||||
itemGap: 0,
|
itemGap: 0,
|
||||||
autoItemHeight: 3,
|
autoItemHeight: 3,
|
||||||
legend: {
|
legend: {
|
||||||
|
type: 'plain',
|
||||||
orient: 'horizontal',
|
orient: 'horizontal',
|
||||||
|
width: '100%',
|
||||||
bottom: 10,
|
bottom: 10,
|
||||||
left: 'center',
|
left: 'center',
|
||||||
|
itemWidth: 16,
|
||||||
|
itemHeight: 16,
|
||||||
|
itemGap: itemGapWith.value ? itemGapWith.value : 50,
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: '16px',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
text: '23亿元',
|
text: '23亿元',
|
||||||
@ -47,18 +68,18 @@ const option = reactive({
|
|||||||
color: '#02FD94',
|
color: '#02FD94',
|
||||||
fontSize: '18px',
|
fontSize: '18px',
|
||||||
},
|
},
|
||||||
top: 'center',
|
top: '26%',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
},
|
},
|
||||||
grid3D: {
|
grid3D: {
|
||||||
show: false,
|
show: false,
|
||||||
boxHeight: 5,
|
boxHeight: 3,
|
||||||
top: 'center',
|
top: '-15%', //调整距离顶部距离,0是在中间
|
||||||
left: 'center',
|
left: 'center',
|
||||||
viewControl: {
|
viewControl: {
|
||||||
//3d效果可以放大、旋转等,请自己去查看官方配置
|
//3d效果可以放大、旋转等,请自己去查看官方配置
|
||||||
alpha: 30, //角度(这个很重要 调节角度的)
|
alpha: 36, //角度(这个很重要 调节角度的)
|
||||||
distance: 160, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
distance: 130, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||||
rotateSensitivity: 10, //设置旋转灵敏度,为0无法旋转
|
rotateSensitivity: 10, //设置旋转灵敏度,为0无法旋转
|
||||||
zoomSensitivity: 10, //设置缩放灵敏度,为0无法缩放
|
zoomSensitivity: 10, //设置缩放灵敏度,为0无法缩放
|
||||||
panSensitivity: 10, //设置平移灵敏度,0无法平移
|
panSensitivity: 10, //设置平移灵敏度,0无法平移
|
||||||
@ -73,6 +94,10 @@ const option = reactive({
|
|||||||
// #region
|
// #region
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
onMounted(() => {
|
||||||
|
itemGapWith.value = getChartrefWith();
|
||||||
|
option.legend.itemGap = itemGapWith.value ? itemGapWith.value : 50;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
@ -1,34 +1,21 @@
|
|||||||
<template>
|
<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>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive } from 'vue';
|
import { reactive, watch } from 'vue';
|
||||||
let dataList = reactive([
|
import { isEmpty, sleep } from '@/utils';
|
||||||
{
|
|
||||||
value: 10,
|
const props = defineProps({
|
||||||
name: '2020',
|
data: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
},
|
},
|
||||||
{
|
query: {
|
||||||
value: 66,
|
type: String,
|
||||||
name: '2021',
|
default: '',
|
||||||
},
|
},
|
||||||
{
|
});
|
||||||
value: 100,
|
|
||||||
name: '2022',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 120,
|
|
||||||
name: '2023',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 150,
|
|
||||||
name: '2024',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 80,
|
|
||||||
name: '2025',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
option: {
|
option: {
|
||||||
color: ['#35D0C0'],
|
color: ['#35D0C0'],
|
||||||
@ -44,7 +31,9 @@ const state = reactive({
|
|||||||
axisPointer: {
|
axisPointer: {
|
||||||
type: 'shadow',
|
type: 'shadow',
|
||||||
},
|
},
|
||||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
// tooltip样式调整添加这个类名
|
||||||
|
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5);',
|
||||||
borderColor: '#35d0c0',
|
borderColor: '#35d0c0',
|
||||||
formatter: (data) => {
|
formatter: (data) => {
|
||||||
const params = data[0];
|
const params = data[0];
|
||||||
@ -76,12 +65,12 @@ const state = reactive({
|
|||||||
// name: '',
|
// name: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: dataList,
|
data: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const refresData = () => {
|
const refresData = () => {
|
||||||
console.info('landPatrol********************refresData');
|
// console.info('landPatrol********************refresData');
|
||||||
state.data = dataList = reactive([
|
state.data = reactive([
|
||||||
{
|
{
|
||||||
value: 20,
|
value: 20,
|
||||||
name: '2020',
|
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({
|
defineExpose({
|
||||||
refresData,
|
refresData,
|
||||||
});
|
});
|
||||||
|
@ -2,43 +2,48 @@
|
|||||||
<custom-echart-column-line :chart-data="state.data" height="100%" :option="state.option" />
|
<custom-echart-column-line :chart-data="state.data" height="100%" :option="state.option" />
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive } from 'vue';
|
import { reactive, watch } from 'vue';
|
||||||
|
import { isEmpty, sleep } from '@/utils';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
data: [
|
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: '大兴乡' },
|
|
||||||
],
|
|
||||||
option: {
|
option: {
|
||||||
grid: {
|
grid: {
|
||||||
left: '3%',
|
left: '3%',
|
||||||
right: '10%',
|
right: '1%',
|
||||||
bottom: '10%',
|
bottom: '10%',
|
||||||
top: '15%',
|
top: '15%',
|
||||||
containLabel: true,
|
containLabel: true,
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
show: true,
|
||||||
trigger: 'axis',
|
trigger: 'axis',
|
||||||
axisPointer: {
|
axisPointer: {
|
||||||
type: 'shadow',
|
type: 'shadow',
|
||||||
},
|
},
|
||||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
// tooltip样式调整添加这个类名
|
||||||
|
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||||
borderColor: '#35d0c0',
|
borderColor: '#35d0c0',
|
||||||
formatter: (data) => {
|
formatter: (data) => {
|
||||||
console.log('data', data);
|
console.log('data', data);
|
||||||
const params = data[0];
|
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.name}</span><br/>
|
||||||
<span>${params.marker} ${params.data} 万</span><br />
|
<span>${params.marker} ${params.data} 万吨</span><br />
|
||||||
<span>${data[1].marker} ${data[1].data} 万</span>
|
<span>${data[1].marker} ${data[1].data} 万吨</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
@ -130,14 +135,14 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
legend: {
|
legend: {
|
||||||
itemWidth: 12,
|
itemWidth: 16,
|
||||||
itemHeight: 8,
|
itemHeight: 16,
|
||||||
itemGap: 20,
|
itemGap: 20,
|
||||||
right: '2%',
|
right: '2%',
|
||||||
top: '3%',
|
top: '3%',
|
||||||
x: 'center',
|
x: 'center',
|
||||||
textStyle: {
|
textStyle: {
|
||||||
fontSize: 14,
|
fontSize: 16,
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
},
|
},
|
||||||
data: ['总产量(吨)', '平均产量(吨)'],
|
data: ['总产量(吨)', '平均产量(吨)'],
|
||||||
@ -156,12 +161,12 @@ const state = reactive({
|
|||||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
{
|
{
|
||||||
offset: 0,
|
offset: 0,
|
||||||
color: 'rgba(53,208,192,1)',
|
color: 'rgba(1,254,253,1)',
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
offset: 1,
|
offset: 1,
|
||||||
color: 'rgba(53,208,192,0)',
|
color: 'rgba(1,254,253,0)',
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
@ -180,23 +185,72 @@ const state = reactive({
|
|||||||
name: '平均产量(吨)',
|
name: '平均产量(吨)',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
yAxisIndex: 1,
|
yAxisIndex: 1,
|
||||||
showSymbol: true,
|
showSymbol: false,
|
||||||
symbolSize: 8,
|
symbolSize: 8,
|
||||||
smooth: true,
|
smooth: false,
|
||||||
symbol: 'circle',
|
symbol: 'circle',
|
||||||
max: 100,
|
max: 100,
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
normal: {
|
normal: {
|
||||||
color: 'rgba(53,208,192,1)',
|
color: '#FEF906',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: 'rgba(254,249,6,1)',
|
color: '#FEF906',
|
||||||
borderColor: '#fff',
|
|
||||||
borderWidth: 1,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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>
|
</script>
|
||||||
|
@ -1,34 +1,40 @@
|
|||||||
<template>
|
<template>
|
||||||
<customEchartHyalineCake :chart-data="data" height="100%" :option="option" />
|
<customEchartHyalineCake :chart-data="dataList" height="100%" :option="option" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
|
|
||||||
/* --------------- data --------------- */
|
/* --------------- 左中饼图 --------------- */
|
||||||
// #region
|
// #region
|
||||||
const data = ref([
|
const dataList = ref([
|
||||||
{
|
{
|
||||||
name: '烟草',
|
name: '烟草',
|
||||||
value: 60.8,
|
value: 60.8,
|
||||||
|
money: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '甘蔗',
|
name: '甘蔗',
|
||||||
value: 44.4,
|
value: 44.4,
|
||||||
|
money: 88,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '核桃',
|
name: '核桃',
|
||||||
value: 24.3,
|
value: 24.3,
|
||||||
|
money: 92,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '蔬菜',
|
name: '蔬菜',
|
||||||
value: 32.7,
|
value: 32.7,
|
||||||
|
money: 56,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '其他',
|
name: '其他',
|
||||||
value: 32.9,
|
value: 32.9,
|
||||||
|
money: 18,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const option = reactive({
|
const option = reactive({
|
||||||
k: 0.3,
|
k: 0.3,
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
@ -36,13 +42,13 @@ const option = reactive({
|
|||||||
autoItemHeight: 2,
|
autoItemHeight: 2,
|
||||||
grid3D: {
|
grid3D: {
|
||||||
show: false,
|
show: false,
|
||||||
boxHeight: 5,
|
boxHeight: 4, //厚度
|
||||||
top: '0',
|
top: '0', //距离顶部的距离
|
||||||
left: '-20%',
|
left: '-20%',
|
||||||
viewControl: {
|
viewControl: {
|
||||||
//3d效果可以放大、旋转等,请自己去查看官方配置
|
//3d效果可以放大、旋转等,请自己去查看官方配置
|
||||||
alpha: 30, //角度(这个很重要 调节角度的)
|
alpha: 30, //角度(这个很重要 调节角度的)
|
||||||
distance: 160, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
distance: 200, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||||
rotateSensitivity: 10, //设置旋转灵敏度,为0无法旋转
|
rotateSensitivity: 10, //设置旋转灵敏度,为0无法旋转
|
||||||
zoomSensitivity: 10, //设置缩放灵敏度,为0无法缩放
|
zoomSensitivity: 10, //设置缩放灵敏度,为0无法缩放
|
||||||
panSensitivity: 10, //设置平移灵敏度,0无法平移
|
panSensitivity: 10, //设置平移灵敏度,0无法平移
|
||||||
@ -50,6 +56,41 @@ const option = reactive({
|
|||||||
autoRotateAfterStill: 2, //在鼠标静止操作后恢复自动旋转的时间间隔,在开启 autoRotate 后有效
|
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
|
// #endregion
|
||||||
|
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="chartsWarp" class="hot-charts">
|
<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" />
|
<custom-echart-triangle :chart-data="data" height="100%" :option="option" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -7,15 +12,78 @@
|
|||||||
import { ref, reactive, onMounted } from 'vue';
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
|
|
||||||
const data = ref([
|
const data = ref([
|
||||||
{ value: 40, name: '一级', reaVal: '20' },
|
{ value: 40, name: '一级', reaVal: '20', itemStyle: { color: '#56b1c0' } },
|
||||||
{ value: 80, name: '二级', reaVal: '30' },
|
{ value: 80, name: '二级', reaVal: '30', itemStyle: { color: '#77c8ca' } },
|
||||||
{ value: 120, name: '三级', reaVal: '50' },
|
{ value: 120, name: '三级', reaVal: '50', itemStyle: { color: '#7bb9cf' } },
|
||||||
]);
|
]);
|
||||||
const option = reactive({});
|
const option = reactive({});
|
||||||
onMounted(() => {});
|
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>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.hot-charts {
|
.hot-charts {
|
||||||
|
width: 100%;
|
||||||
height: 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>
|
</style>
|
||||||
|
@ -2,9 +2,29 @@
|
|||||||
<el-row class="data-home-index">
|
<el-row class="data-home-index">
|
||||||
<el-col :span="6" class="left-charts">
|
<el-col :span="6" class="left-charts">
|
||||||
<div class="left-charts-item">
|
<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>
|
<template #back>
|
||||||
<entitiesCategoryCharts></entitiesCategoryCharts>
|
<entitiesCategoryCharts ref="oneRef" :data="state.data.one" :query="state.queryCode"></entitiesCategoryCharts>
|
||||||
</template>
|
</template>
|
||||||
</customBack>
|
</customBack>
|
||||||
</div>
|
</div>
|
||||||
@ -16,9 +36,25 @@
|
|||||||
</customBack>
|
</customBack>
|
||||||
</div>
|
</div>
|
||||||
<div class="left-charts-item">
|
<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>
|
<template #back>
|
||||||
<entitiesStatistics></entitiesStatistics>
|
<entitiesStatistics ref="thirdRef" :data="state.data.third" :query="state.contrastCode"></entitiesStatistics>
|
||||||
</template>
|
</template>
|
||||||
</customBack>
|
</customBack>
|
||||||
</div>
|
</div>
|
||||||
@ -52,6 +88,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { nextTick, reactive, ref } from 'vue';
|
||||||
import centerMap from '@/components/centerMap.vue';
|
import centerMap from '@/components/centerMap.vue';
|
||||||
import categoryCharts from './components/categoryCharts.vue';
|
import categoryCharts from './components/categoryCharts.vue';
|
||||||
import entitieslist from './components/entitieslist.vue';
|
import entitieslist from './components/entitieslist.vue';
|
||||||
@ -60,6 +97,58 @@ import benefitCharts from './components/benefitCharts.vue';
|
|||||||
import entitiesStatistics from './components/entitiesStatistics.vue';
|
import entitiesStatistics from './components/entitiesStatistics.vue';
|
||||||
import entitiesCategoryCharts from './components/entitiesCategoryCharts.vue';
|
import entitiesCategoryCharts from './components/entitiesCategoryCharts.vue';
|
||||||
import entitiesMap from './components/entitiesMap.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>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.data-home-index {
|
.data-home-index {
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<div class="data-home-index">
|
<div class="data-home-index">
|
||||||
<template v-for="(n, index) in homeList" :key="n.name">
|
<template v-for="(n, index) in homeList" :key="n.name">
|
||||||
<div class="home-enter-item" :style="n.style" @click="itemClick(index)">
|
<div class="home-enter-item" :style="n.style" @click="itemClick(index)">
|
||||||
<div class="name">
|
<div class="name" :style="n.nameStyle">
|
||||||
<span>{{ n.title || '--' }}</span>
|
<span :style="n.spanStyle">{{ n.title || '--' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="img-icon" :style="n.imgstyle"><img :src="getAssetsFile(n.img)" /></div>
|
<div class="img-icon" :style="n.imgstyle"><img :src="getAssetsFile(n.img)" /></div>
|
||||||
</div>
|
</div>
|
||||||
@ -32,17 +32,21 @@ let homeList = reactive([
|
|||||||
linkType: 0,
|
linkType: 0,
|
||||||
url: '',
|
url: '',
|
||||||
img: 'images/vsualized/home1.png',
|
img: 'images/vsualized/home1.png',
|
||||||
style: 'left: 20%;bottom:320px;',
|
style: 'left: 21%;bottom:300px;',
|
||||||
imgstyle: 'width:100px;height:100px',
|
imgstyle: 'width:100px;height:100px',
|
||||||
|
nameStyle: 'padding: 0 16px;margin: 16px 0;',
|
||||||
|
spanStyle: 'font-size: 20px;',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '农业产业运营服务平台',
|
title: '产业运营平台',
|
||||||
name: 'operation',
|
name: 'operation',
|
||||||
linkType: 0,
|
linkType: 0,
|
||||||
url: '',
|
url: '',
|
||||||
img: 'images/vsualized/home2.png',
|
img: 'images/vsualized/home2.png',
|
||||||
style: 'left: 20%;bottom: 64px;',
|
style: 'left: 22%;bottom: 24px;',
|
||||||
imgstyle: 'width:160px;height:160px',
|
imgstyle: 'width:160px;height:160px',
|
||||||
|
nameStyle: 'padding: 0 22px;margin: 24px 0;border-radius: 16px;',
|
||||||
|
spanStyle: 'font-size: 28px;line-height: 66px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '数字大屏',
|
title: '数字大屏',
|
||||||
@ -50,17 +54,21 @@ let homeList = reactive([
|
|||||||
linkType: 1,
|
linkType: 1,
|
||||||
url: '/new-digital-agriculture-screen/v2/land',
|
url: '/new-digital-agriculture-screen/v2/land',
|
||||||
img: 'images/vsualized/home3.png',
|
img: 'images/vsualized/home3.png',
|
||||||
style: 'right: 20%;bottom:320px;',
|
style: 'right: 23%;bottom:300px;',
|
||||||
imgstyle: 'width:100px;height:100px',
|
imgstyle: 'width:100px;height:100px',
|
||||||
|
nameStyle: 'padding: 0 16px;margin: 16px 0;',
|
||||||
|
spanStyle: 'font-size: 20px;',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '农业产业政务服务平台',
|
title: '政务云平台',
|
||||||
name: 'gov',
|
name: 'gov',
|
||||||
linkType: 0,
|
linkType: 0,
|
||||||
url: '',
|
url: '',
|
||||||
img: 'images/vsualized/home4.png',
|
img: 'images/vsualized/home4.png',
|
||||||
style: 'right: 20%;bottom: 64px;',
|
style: 'right: 24%;bottom: 24px;',
|
||||||
imgstyle: 'width:160px;height:160px',
|
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 {
|
.name {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-family: 'JinBuTi';
|
font-family: 'JinBuTi';
|
||||||
margin: 24px 0;
|
|
||||||
background: linear-gradient(180deg, #01fefd, rgba(1, 254, 253, 0));
|
|
||||||
border: 2px solid #01fefd;
|
border: 2px solid #01fefd;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
padding: 0 24px;
|
&::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 {
|
span {
|
||||||
backdrop-filter: blur(8px);
|
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
text-shadow: 0px 4px 8px 0px #01fefd;
|
text-shadow: 0px 4px 8px 0px #01fefd;
|
||||||
font-size: 28px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.img-icon {
|
.img-icon {
|
||||||
|
@ -23,20 +23,22 @@ const state = reactive({
|
|||||||
containLabel: true,
|
containLabel: true,
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
className: 'custom-tooltip-container',
|
||||||
trigger: 'axis',
|
trigger: 'axis',
|
||||||
axisPointer: {
|
axisPointer: {
|
||||||
type: 'shadow',
|
type: 'shadow',
|
||||||
},
|
},
|
||||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
backgroundColor: 'rgba(0,0,0,0.6);',
|
||||||
borderColor: '#35d0c0',
|
borderColor: '#35d0c0',
|
||||||
formatter: (data) => {
|
formatter: (data) => {
|
||||||
const params = data[0];
|
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.name}</span><br/>
|
||||||
<span>${params.marker} ${params.data} 万元</span>
|
<span>${params.marker} ${params.data} 万亩</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
|
extraCssText: 'backdrop-filter: blur(8px);',
|
||||||
},
|
},
|
||||||
barStyle: {
|
barStyle: {
|
||||||
barWidth: 14,
|
barWidth: 14,
|
||||||
@ -46,13 +48,13 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
type: 'linear',
|
type: 'linear',
|
||||||
x: 0,
|
x: 1,
|
||||||
y: 0,
|
y: 0,
|
||||||
x2: 0,
|
x2: 0,
|
||||||
y2: 1,
|
y2: 0,
|
||||||
colorStops: [
|
colorStops: [
|
||||||
{ offset: 0, color: '#35D0C0' },
|
{ offset: 0, color: '#35D0C0' },
|
||||||
{ offset: 1, color: '#35D0C0' },
|
{ offset: 1, color: 'rgba(53,208,192,0)' },
|
||||||
],
|
],
|
||||||
global: false,
|
global: false,
|
||||||
},
|
},
|
||||||
|
@ -128,16 +128,15 @@ const _circleNum = computed(() => {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
&.active {
|
&.active {
|
||||||
background-color: rgba($color: #4aeb82, $alpha: 0.4);
|
background: rgba(38, 122, 102, 0.3);
|
||||||
border: 1px solid rgba($color: #008f32, $alpha: 08);
|
border: 1px solid #35d0c0;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
.spot {
|
.spot {
|
||||||
transform: scale(1.2);
|
transform: scale(1.2);
|
||||||
}
|
}
|
||||||
._label,
|
._label {
|
||||||
._value {
|
font-size: 16px;
|
||||||
font-size: 18px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
._label {
|
._label {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<centerMap :dialog-title="'土地类型'" @mapclick="doMapclick">
|
<centerMap class="land-map-body" :dialog-title="'土地类型'" @mapclick="doMapclick">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="land-map-pop-header">
|
<div class="land-map-pop-header">
|
||||||
<div class="title">土地类型</div>
|
<div class="title">土地类型</div>
|
||||||
@ -49,6 +49,11 @@ const all = computed(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.land-map-body {
|
||||||
|
:deep(.el-dialog__body) {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
.land-map-pop-header {
|
.land-map-pop-header {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -22,25 +22,27 @@ const state = reactive({
|
|||||||
containLabel: true,
|
containLabel: true,
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
className: 'custom-tooltip-container', // 自定义父容器类名
|
||||||
trigger: 'axis',
|
trigger: 'axis',
|
||||||
axisPointer: {
|
axisPointer: {
|
||||||
type: 'shadow',
|
type: 'shadow',
|
||||||
},
|
},
|
||||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
backgroundColor: 'rgba(0,0,0,0.5);',
|
||||||
borderColor: '#35d0c0',
|
borderColor: '#35d0c0',
|
||||||
formatter: (data) => {
|
formatter: (data) => {
|
||||||
const params = data[0];
|
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.name}</span><br/>
|
||||||
<span>${params.marker} ${params.data} 万亩</span>
|
<span>${params.marker} ${params.data} 万亩</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
|
extraCssText: 'backdrop-filter: blur(8px);',
|
||||||
},
|
},
|
||||||
barStyle: {
|
barStyle: {
|
||||||
barWidth: 15,
|
barWidth: 16,
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
borderRadius: [8, 8, 0, 0], // 设置柱子的圆角半径
|
borderRadius: 8, // 设置柱子的圆角半径
|
||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
type: 'linear',
|
type: 'linear',
|
||||||
@ -49,23 +51,14 @@ const state = reactive({
|
|||||||
x2: 0,
|
x2: 0,
|
||||||
y2: 1,
|
y2: 1,
|
||||||
colorStops: [
|
colorStops: [
|
||||||
{ offset: 0, color: '#35D0C0' },
|
{ offset: 0, color: '#35d0c0' },
|
||||||
{ offset: 1, color: '#35D0C0' },
|
{ offset: 1, color: 'rgba(53,208,192,0)' },
|
||||||
],
|
],
|
||||||
global: false,
|
global: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
// name: '面积',
|
|
||||||
// splitLine: {
|
|
||||||
// show: false,
|
|
||||||
// lineStyle: {
|
|
||||||
// type: 'dashed',
|
|
||||||
// color: '',
|
|
||||||
// width: 1,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
axisTick: {
|
axisTick: {
|
||||||
show: false,
|
show: false,
|
||||||
alignWithLabel: false,
|
alignWithLabel: false,
|
||||||
@ -78,44 +71,11 @@ const state = reactive({
|
|||||||
color: 'rgba(28, 158, 222, 1)',
|
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: {
|
yAxis: {
|
||||||
type: 'value',
|
type: 'value',
|
||||||
// name: '面积(万亩)',
|
// 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: [],
|
data: [],
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<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>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -15,23 +15,24 @@ const props = defineProps({
|
|||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
option: {
|
option: {
|
||||||
opacity: 0.6,
|
k: 0.5,
|
||||||
itemGap: 0.2,
|
opacity: 1,
|
||||||
|
itemGap: 0.1,
|
||||||
legendSuffix: '万亩',
|
legendSuffix: '万亩',
|
||||||
itemHeight: 120,
|
itemHeight: 200,
|
||||||
grid3D: {
|
grid3D: {
|
||||||
show: false,
|
show: false,
|
||||||
boxHeight: 5,
|
boxHeight: 1,
|
||||||
top: '0',
|
top: '0',
|
||||||
left: '-20%',
|
left: '-20%',
|
||||||
viewControl: {
|
viewControl: {
|
||||||
//3d效果可以放大、旋转等,请自己去查看官方配置
|
//3d效果可以放大、旋转等,请自己去查看官方配置
|
||||||
alpha: 30, //角度(这个很重要 调节角度的)
|
alpha: 45, //角度(这个很重要 调节角度的)
|
||||||
distance: 260, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
distance: 300, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||||
rotateSensitivity: 10, //设置旋转灵敏度,为0无法旋转
|
rotateSensitivity: 10, //设置旋转灵敏度,为0无法旋转
|
||||||
zoomSensitivity: 10, //设置缩放灵敏度,为0无法缩放
|
zoomSensitivity: 10, //设置缩放灵敏度,为0无法缩放
|
||||||
panSensitivity: 10, //设置平移灵敏度,0无法平移
|
panSensitivity: 10, //设置平移灵敏度,0无法平移
|
||||||
autoRotate: true, //自动旋转
|
autoRotate: false, //自动旋转
|
||||||
autoRotateAfterStill: 2, //在鼠标静止操作后恢复自动旋转的时间间隔,在开启 autoRotate 后有效
|
autoRotateAfterStill: 2, //在鼠标静止操作后恢复自动旋转的时间间隔,在开启 autoRotate 后有效
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -27,11 +27,12 @@ const state = reactive({
|
|||||||
containLabel: true,
|
containLabel: true,
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
className: 'custom-tooltip-container',
|
||||||
trigger: 'axis',
|
trigger: 'axis',
|
||||||
axisPointer: {
|
axisPointer: {
|
||||||
type: 'shadow',
|
type: 'shadow',
|
||||||
},
|
},
|
||||||
backgroundColor: 'rgba(18, 55, 85, 0.8);',
|
backgroundColor: 'rgba(0,0,0,0.6);',
|
||||||
borderColor: '#35d0c0',
|
borderColor: '#35d0c0',
|
||||||
formatter: (data) => {
|
formatter: (data) => {
|
||||||
const params = data[0];
|
const params = data[0];
|
||||||
@ -41,6 +42,7 @@ const state = reactive({
|
|||||||
</div>`;
|
</div>`;
|
||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
|
extraCssText: 'backdrop-filter: blur(8px);',
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
@ -60,7 +62,6 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: 'value',
|
type: 'value',
|
||||||
// name: '',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: [],
|
data: [],
|
||||||
|
@ -20,10 +20,10 @@ const state = reactive({
|
|||||||
option: {
|
option: {
|
||||||
// 数据
|
// 数据
|
||||||
dataset: [],
|
dataset: [],
|
||||||
type: 'column',
|
type: 'row',
|
||||||
rowNum: 6,
|
rowNum: 6,
|
||||||
isAnimation: true,
|
isAnimation: true,
|
||||||
waitTime: 5,
|
waitTime: 2,
|
||||||
unit: '万元',
|
unit: '万元',
|
||||||
sort: true,
|
sort: true,
|
||||||
height: 12,
|
height: 12,
|
||||||
@ -32,9 +32,9 @@ const state = reactive({
|
|||||||
borderRadius: '12px',
|
borderRadius: '12px',
|
||||||
carousel: 'single',
|
carousel: 'single',
|
||||||
indexPrefix: 'TOP',
|
indexPrefix: 'TOP',
|
||||||
indexFontSize: 12,
|
indexFontSize: 20,
|
||||||
leftFontSize: 14,
|
leftFontSize: 16,
|
||||||
rightFontSize: 14,
|
rightFontSize: 16,
|
||||||
valueFormatter: (item) => {
|
valueFormatter: (item) => {
|
||||||
return item.value;
|
return item.value;
|
||||||
},
|
},
|
||||||
@ -61,8 +61,11 @@ watch(
|
|||||||
&:deep(.row-item) {
|
&:deep(.row-item) {
|
||||||
.ranking-info {
|
.ranking-info {
|
||||||
color: #35d0c0 !important;
|
color: #35d0c0 !important;
|
||||||
font-family: 'DingTalk JinBuTi, DingTalk JinBuTi-Regular';
|
font-weight: 400;
|
||||||
font-weight: 700;
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.ranking-value {
|
||||||
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inside-column {
|
.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>
|
</customBack>
|
||||||
</div>
|
</div>
|
||||||
<div class="left-charts-item">
|
<div class="left-charts-item">
|
||||||
<customBack top-title="农村土地资源项目效益" :top-postion="'left'">
|
<customBack top-title="农村土地资源" :top-postion="'left'">
|
||||||
<template #back>
|
<template #back>
|
||||||
<landTwo :data="state.data.two" />
|
<landTwo :data="state.data.two" />
|
||||||
</template>
|
</template>
|
||||||
@ -55,14 +55,31 @@
|
|||||||
</customBack>
|
</customBack>
|
||||||
</div>
|
</div>
|
||||||
<div class="right-charts-item">
|
<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>
|
<template #back>
|
||||||
<landFive :data="state.data.five" />
|
<landFive :data="state.data.five" />
|
||||||
</template>
|
</template>
|
||||||
</customBack>
|
</customBack>
|
||||||
</div>
|
</div>
|
||||||
<div class="right-charts-item">
|
<div class="right-charts-item">
|
||||||
<customBack top-title="各地农用地利用面积" :top-postion="'right'">
|
<customBack top-title="全县作物情况" :top-postion="'right'">
|
||||||
<template #back>
|
<template #back>
|
||||||
<landSix :data="state.data.six" />
|
<landSix :data="state.data.six" />
|
||||||
</template>
|
</template>
|
||||||
@ -198,9 +215,22 @@ const handleCommand = (data) => {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
::v-deep(.custom-back-content) {
|
||||||
|
padding: 8px !important; /* 强制覆盖 padding */
|
||||||
|
}
|
||||||
|
|
||||||
.data-home-index {
|
.data-home-index {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 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 {
|
.left-charts {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
|
@ -23,10 +23,7 @@ import { resolve } from 'path';
|
|||||||
const useDevMode = true;
|
const useDevMode = true;
|
||||||
|
|
||||||
export default defineConfig(({ command, mode }) => {
|
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(
|
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());
|
||||||
mode,
|
|
||||||
process.cwd()
|
|
||||||
);
|
|
||||||
const config = {
|
const config = {
|
||||||
base: '/new-digital-agriculture-screen/',
|
base: '/new-digital-agriculture-screen/',
|
||||||
build: {
|
build: {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,18 +8,18 @@ const annualplanRoutes = [
|
|||||||
redirect: '/sub-government-affairs-service/annualPlans',
|
redirect: '/sub-government-affairs-service/annualPlans',
|
||||||
meta: { title: '年度种植计划', icon: '' },
|
meta: { title: '年度种植计划', icon: '' },
|
||||||
children: [
|
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',
|
path: '/sub-government-affairs-service/annualPlans',
|
||||||
name: 'annualPlans',
|
name: 'annualPlans',
|
||||||
component: () => import('@/views/annualPlan/component/annualPlans/index.vue'),
|
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',
|
path: '/sub-government-affairs-service/region',
|
||||||
name: 'region',
|
name: 'region',
|
||||||
component: () => import('@/views/dict/component/region/index.vue'),
|
component: () => import('@/views/dict/component/region/index.vue'),
|
||||||
meta: { title: '行政区域信息', icon: '' },
|
meta: { title: '行政信息', icon: '' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/landCassification',
|
path: '/sub-government-affairs-service/landCassification',
|
||||||
@ -21,18 +21,18 @@ const dictRoutes = [
|
|||||||
component: () => import('@/views/dict/component/landCassification/index.vue'),
|
component: () => import('@/views/dict/component/landCassification/index.vue'),
|
||||||
meta: { title: '土地分类', icon: '' },
|
meta: { title: '土地分类', icon: '' },
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
path: '/sub-government-affairs-service/dictCrop',
|
// path: '/sub-government-affairs-service/dictCrop',
|
||||||
name: 'dictCrop',
|
// name: 'dictCrop',
|
||||||
component: () => import('@/views/dict/component/dictCrop/index.vue'),
|
// component: () => import('@/views/dict/component/dictCrop/index.vue'),
|
||||||
meta: { title: '种植产物信息', icon: '' },
|
// meta: { title: '种植产物信息', icon: '' },
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: '/sub-government-affairs-service/soilClassification',
|
// path: '/sub-government-affairs-service/soilClassification',
|
||||||
name: 'soilClassification',
|
// name: 'soilClassification',
|
||||||
component: () => import('@/views/dict/component/soilClassification/index.vue'),
|
// component: () => import('@/views/dict/component/soilClassification/index.vue'),
|
||||||
meta: { title: '土壤分类', icon: '' },
|
// meta: { title: '土壤分类', icon: '' },
|
||||||
},
|
// },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -38,7 +38,7 @@ const inputSuppliesRoutes = [
|
|||||||
path: '/sub-government-affairs-service/material/pesticide',
|
path: '/sub-government-affairs-service/material/pesticide',
|
||||||
name: 'input-supplies-pesticide',
|
name: 'input-supplies-pesticide',
|
||||||
component: () => import('@/views/inputSuppliesManage/material/pesticide/index.vue'),
|
component: () => import('@/views/inputSuppliesManage/material/pesticide/index.vue'),
|
||||||
meta: { title: '农药管理', icon: 'Document' },
|
meta: { title: '农药管理', icon: '' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/material/ratPoison',
|
path: '/sub-government-affairs-service/material/ratPoison',
|
||||||
@ -70,7 +70,7 @@ const inputSuppliesRoutes = [
|
|||||||
path: '/sub-government-affairs-service/enterpriseDealerCheck',
|
path: '/sub-government-affairs-service/enterpriseDealerCheck',
|
||||||
name: 'enterpriseDealerCheck',
|
name: 'enterpriseDealerCheck',
|
||||||
component: () => import('@/views/inputSuppliesManage/enterpriseDealerCheck/index.vue'),
|
component: () => import('@/views/inputSuppliesManage/enterpriseDealerCheck/index.vue'),
|
||||||
meta: { title: '企业经销商抽检', icon: 'Document' },
|
meta: { title: '企业经销商抽检', icon: '' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/useSupervise',
|
path: '/sub-government-affairs-service/useSupervise',
|
||||||
|
@ -6,20 +6,20 @@ const landsRoutes = [
|
|||||||
path: '/sub-government-affairs-service/landManage',
|
path: '/sub-government-affairs-service/landManage',
|
||||||
name: 'landManage',
|
name: 'landManage',
|
||||||
component: Views,
|
component: Views,
|
||||||
redirect: '/sub-government-affairs-service/landsManage',
|
redirect: '/sub-government-affairs-service/plantPlan',
|
||||||
meta: { title: '土地管理', icon: 'Grape' },
|
meta: { title: '土地管理', icon: 'Grape' },
|
||||||
children: [
|
children: [
|
||||||
{
|
// {
|
||||||
path: '/sub-government-affairs-service/landsManage',
|
// path: '/sub-government-affairs-service/landsManage',
|
||||||
name: 'landsManage',
|
// name: 'landsManage',
|
||||||
component: () => import('@/views/landManage/component/landsManage/index.vue'),
|
// component: () => import('@/views/landManage/component/landsManage/index.vue'),
|
||||||
meta: { title: '土地信息登记', icon: '' },
|
// meta: { title: '土地信息登记', icon: '' },
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/plantPlan',
|
path: '/sub-government-affairs-service/plantPlan',
|
||||||
name: 'plantPlan',
|
name: 'plantPlan',
|
||||||
component: () => import('@/views/landManage/component/plantPlan/index.vue'),
|
component: () => import('@/views/landManage/component/plantPlan/index.vue'),
|
||||||
meta: { title: '种植规划', icon: '' },
|
meta: { title: '种植计划', icon: '' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/operationRecord',
|
path: '/sub-government-affairs-service/operationRecord',
|
||||||
|
@ -13,10 +13,25 @@ export default [
|
|||||||
meta: { title: '土地资源管理', icon: 'icon-test' },
|
meta: { title: '土地资源管理', icon: 'icon-test' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
redirect: '/sub-government-affairs-service/grid',
|
||||||
path: '/sub-government-affairs-service/grid',
|
path: '/sub-government-affairs-service/grid',
|
||||||
component: () => import('@/views/resource/grid/index.vue'),
|
component: () => import('@/views/resource/grid/index.vue'),
|
||||||
name: 'grid',
|
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,
|
...annualplanRouters,
|
||||||
...landsRoutes,
|
...landsRoutes,
|
||||||
|
@ -30,26 +30,26 @@ export default [
|
|||||||
path: '/sub-government-affairs-service/system-dept',
|
path: '/sub-government-affairs-service/system-dept',
|
||||||
component: () => import('@/views/system/dept/index.vue'),
|
component: () => import('@/views/system/dept/index.vue'),
|
||||||
name: 'system-dept',
|
name: 'system-dept',
|
||||||
meta: { title: '部门管理', icon: 'Document' },
|
meta: { title: '部门管理', icon: '' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/system-role',
|
path: '/sub-government-affairs-service/system-role',
|
||||||
component: () => import('@/views/system/role/index.vue'),
|
component: () => import('@/views/system/role/index.vue'),
|
||||||
name: 'system-role',
|
name: 'system-role',
|
||||||
meta: { title: '角色管理', icon: 'Document' },
|
meta: { title: '角色管理', icon: '' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/system-auth-user',
|
path: '/sub-government-affairs-service/system-auth-user',
|
||||||
component: () => import('@/views/system/role/authUser.vue'),
|
component: () => import('@/views/system/role/authUser.vue'),
|
||||||
name: 'system-auth-user',
|
name: 'system-auth-user',
|
||||||
meta: { title: '分配用户', icon: 'Document' },
|
meta: { title: '分配用户', icon: '' },
|
||||||
hidden: true,
|
hidden: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/system-user',
|
path: '/sub-government-affairs-service/system-user',
|
||||||
component: () => import('@/views/system/user/index.vue'),
|
component: () => import('@/views/system/user/index.vue'),
|
||||||
name: 'system-user',
|
name: 'system-user',
|
||||||
meta: { title: '用户管理', icon: 'Document' },
|
meta: { title: '用户管理', icon: '' },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -57,7 +57,7 @@ publicAxios.interceptors.request.use(async (config) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config.headers['authorization'] =
|
config.headers['authorization'] =
|
||||||
'eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjozLCJ1c2VyX2tleSI6ImQxNGRhZjMzLWJkODQtNDc1Yy1iMDU3LWE5MmI2OTgyYmY1MyIsInVzZXJuYW1lIjoidGVzdCJ9.3AFekADq1-7-k_OAIQuJterJnVUVCK1rTSYg3X32UHhepBUO95fU-du9joJ_3ZepTrgBHvJApFTqP2x9041THQ';
|
'eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VyX2tleSI6IjVlZmMzZTZlLWEwZTUtNDcxYi05YmU5LWI3NDcwNDQxYTUzMCIsInVzZXJuYW1lIjoiYWRtaW4ifQ.cIgRynK84hfjO6YfW206i3UajKRvIkLBmfYmENeVpbFfYc62gPz9gW8Y3JiU5j5s8KxfuxYqbFP16M5WIppXqw';
|
||||||
if (UserStore.hasToken()) {
|
if (UserStore.hasToken()) {
|
||||||
config.headers['authorization'] = config.headers['authorization'] ?? UserStore.token;
|
config.headers['authorization'] = config.headers['authorization'] ?? UserStore.token;
|
||||||
config.headers['cache-control'] = 'no-cache';
|
config.headers['cache-control'] = 'no-cache';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user