feat
This commit is contained in:
parent
64a09455c4
commit
3677c1e953
2
components.d.ts
vendored
2
components.d.ts
vendored
@ -16,6 +16,8 @@ declare module 'vue' {
|
||||
CustomCarouselPicture: typeof import('./src/components/custom-carousel-picture/index.vue')['default']
|
||||
CustomEchartBar: typeof import('./src/components/custom-echart-bar/index.vue')['default']
|
||||
CustomEchartBubble: typeof import('./src/components/custom-echart-bubble/index.vue')['default']
|
||||
CustomEchartHyaline: typeof import('./src/components/custom-echart-hyaline/index.vue')['default']
|
||||
CustomEchartHyalineCake: typeof import('./src/components/custom-echart-hyaline-cake/index.vue')['default']
|
||||
CustomEchartLine: typeof import('./src/components/custom-echart-line/index.vue')['default']
|
||||
CustomEchartLineLine: typeof import('./src/components/custom-echart-line-line/index.vue')['default']
|
||||
CustomEchartMaps: typeof import('./src/components/custom-echart-maps/index.vue')['default']
|
||||
|
282
src/components/custom-echart-hyaline-cake/index.vue
Normal file
282
src/components/custom-echart-hyaline-cake/index.vue
Normal file
@ -0,0 +1,282 @@
|
||||
<template>
|
||||
<div ref="chartRef" :style="{ height, width }"></div>
|
||||
</template>
|
||||
<script>
|
||||
import { ref, reactive, watchEffect } from 'vue';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { useEcharts } from '@/hooks/useEcharts';
|
||||
export default {
|
||||
name: 'CustomEchartHyalineCake',
|
||||
props: {
|
||||
chartData: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
{
|
||||
name: '项目一',
|
||||
value: 60,
|
||||
},
|
||||
{
|
||||
name: '项目二',
|
||||
value: 44,
|
||||
},
|
||||
{
|
||||
name: '项目三',
|
||||
value: 32,
|
||||
},
|
||||
],
|
||||
},
|
||||
option: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'bar',
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%',
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: 'calc(100vh - 78px)',
|
||||
},
|
||||
isSeries: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['click'],
|
||||
setup(props, { emit }) {
|
||||
const chartRef = ref(null);
|
||||
const { setOptions, getInstance, startAutoPlay } = useEcharts(chartRef);
|
||||
const option = ref({});
|
||||
const itemHeight = ref(120);
|
||||
// let colors = ['#07daf2', '#64de8a', '#ecc23c', '#ffdb5c', '#ff9f7f', '#9fe6b8', '#67e0e3', '#32c5e9', '#fb7293', '#9A60B4', '#ea7ccc'];
|
||||
|
||||
watchEffect(() => {
|
||||
props.chartData && initCharts();
|
||||
});
|
||||
|
||||
function initCharts() {
|
||||
if (props.option) {
|
||||
Object.assign(option, cloneDeep(props.option));
|
||||
}
|
||||
option.value = getPie3D(props.chartData, 0.5);
|
||||
setOptions(option.value);
|
||||
}
|
||||
|
||||
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 = typeof k !== 'undefined' ? k : 1 / 3;
|
||||
const offsetX = Math.cos(midRadian) * 0.2;
|
||||
const offsetY = Math.sin(midRadian) * 0.2;
|
||||
const hoverRate = 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;
|
||||
}
|
||||
return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
|
||||
},
|
||||
};
|
||||
}
|
||||
// 生成模拟 3D 饼图的配置项
|
||||
function getPie3D(pieData) {
|
||||
const series = [];
|
||||
// 总和
|
||||
let sumValue = 0;
|
||||
let startValue = 0;
|
||||
let endValue = 0;
|
||||
const legendData = [];
|
||||
const k = 1;
|
||||
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],
|
||||
|
||||
itemStyle: {
|
||||
// color: colors[i], // 自定义颜色
|
||||
opacity: '0.6',
|
||||
borderRadius: 300,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 0,
|
||||
},
|
||||
pieStatus: {
|
||||
selected: false,
|
||||
hovered: false,
|
||||
k,
|
||||
},
|
||||
};
|
||||
if (typeof pieData[i].itemStyle !== 'undefined') {
|
||||
const { itemStyle } = pieData[i];
|
||||
typeof pieData[i].itemStyle.color !== 'undefined' ? (itemStyle.color = pieData[i].itemStyle.color) : null;
|
||||
typeof pieData[i].itemStyle.opacity !== 'undefined' ? (itemStyle.opacity = pieData[i].itemStyle.opacity) : null;
|
||||
seriesItem.itemStyle = itemStyle;
|
||||
}
|
||||
series.push(seriesItem);
|
||||
}
|
||||
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,
|
||||
itemHeight.value
|
||||
);
|
||||
startValue = endValue;
|
||||
legendData.push(series[i].name);
|
||||
}
|
||||
const option = {
|
||||
tooltip: {
|
||||
position: function (point, params, dom, rect, size) {
|
||||
var x = point[0];
|
||||
var y = point[1];
|
||||
var viewWidth = size.viewSize[0];
|
||||
var viewHeight = size.viewSize[1];
|
||||
var boxWidth = size.contentSize[0];
|
||||
var boxHeight = size.contentSize[1];
|
||||
// 判断 tooltip 位置,调整其位置使其不会超出图表边界
|
||||
if (x + boxWidth > viewWidth) {
|
||||
x = x - boxWidth;
|
||||
}
|
||||
if (y + boxHeight > viewHeight) {
|
||||
y = y - boxHeight;
|
||||
}
|
||||
// 保证 tooltip 始终在图表内部
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
}
|
||||
|
||||
return [x, y];
|
||||
},
|
||||
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.5,
|
||||
},
|
||||
yAxis3D: {
|
||||
min: -1,
|
||||
max: 1.5,
|
||||
},
|
||||
zAxis3D: {
|
||||
min: -1,
|
||||
max: 1.5,
|
||||
},
|
||||
itemGap: 20,
|
||||
grid3D: {
|
||||
itemGap: 20,
|
||||
show: false,
|
||||
boxHeight: 5,
|
||||
top: '0',
|
||||
left: '-20%',
|
||||
viewControl: {
|
||||
//3d效果可以放大、旋转等,请自己去查看官方配置
|
||||
alpha: 60, //角度(这个很重要 调节角度的)
|
||||
distance: 260, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||
rotateSensitivity: 10, //设置旋转灵敏度,为0无法旋转
|
||||
zoomSensitivity: 10, //设置缩放灵敏度,为0无法缩放
|
||||
panSensitivity: 10, //设置平移灵敏度,0无法平移
|
||||
autoRotate: true, //自动旋转
|
||||
autoRotateAfterStill: 2, //在鼠标静止操作后恢复自动旋转的时间间隔,在开启 autoRotate 后有效
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
right: '5%',
|
||||
top: '25%',
|
||||
orient: 'vertical',
|
||||
icon: 'circle',
|
||||
itemHeight: 12,
|
||||
itemWidth: 12,
|
||||
itemGap: 10,
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 14,
|
||||
fontWeight: '400',
|
||||
},
|
||||
formatter: (name) => {
|
||||
if (props.chartData.length) {
|
||||
const item = props.chartData.filter((item) => item.name === name)[0];
|
||||
return ` ${name} ${item.value}万亩`;
|
||||
}
|
||||
},
|
||||
},
|
||||
series,
|
||||
};
|
||||
return option;
|
||||
}
|
||||
function onClick(params) {
|
||||
emit('click', params);
|
||||
}
|
||||
return { chartRef };
|
||||
},
|
||||
};
|
||||
</script>
|
@ -20,6 +20,7 @@ import CustomEchartWordCloud from './custom-echart-word-cloud';
|
||||
import customEchartScatterBlister from './custom-echart-scatter-blister';
|
||||
import customEchartMaps from './custom-echart-maps';
|
||||
import customScrollTitle from './custom-scroll-title';
|
||||
import customEchartHyalineCake from './custom-echart-hyaline-cake';
|
||||
|
||||
export {
|
||||
SvgIcon,
|
||||
@ -44,4 +45,5 @@ export {
|
||||
customEchartScatterBlister,
|
||||
customEchartMaps,
|
||||
customScrollTitle,
|
||||
customEchartHyalineCake,
|
||||
};
|
||||
|
@ -60,7 +60,6 @@ watch(
|
||||
};
|
||||
});
|
||||
list.value.sort((a, b) => b.value - a.value);
|
||||
console.log('list', list.value);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
@ -83,7 +82,6 @@ function handleAc(val) {
|
||||
}
|
||||
const _circleNum = computed(() => {
|
||||
let s = ((currNum.value / allNum.value) * 100).toFixed(1);
|
||||
console.log('s----------', currNum.value, allNum.value, s);
|
||||
return s + '%';
|
||||
});
|
||||
</script>
|
||||
|
44
src/views/land/components/cake.vue
Normal file
44
src/views/land/components/cake.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<customEchartHyalineCake :chart-data="data" height="100%" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
/* --------------- data --------------- */
|
||||
// #region
|
||||
const data = ref([
|
||||
{
|
||||
name: '小麦',
|
||||
value: 60.8,
|
||||
},
|
||||
{
|
||||
name: '荞麦',
|
||||
value: 44.4,
|
||||
},
|
||||
{
|
||||
name: '贡菜',
|
||||
value: 24.3,
|
||||
},
|
||||
{
|
||||
name: '油菜',
|
||||
value: 32.7,
|
||||
},
|
||||
{
|
||||
name: '马铃薯',
|
||||
value: 32.9,
|
||||
},
|
||||
{
|
||||
name: '玉米',
|
||||
value: 32.1,
|
||||
},
|
||||
]);
|
||||
// #endregion
|
||||
|
||||
/* --------------- methods --------------- */
|
||||
// #region
|
||||
|
||||
// #endregion
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -5,6 +5,17 @@
|
||||
import { reactive } from 'vue';
|
||||
|
||||
const state = reactive({
|
||||
data: [
|
||||
{ value: 20, name: '耿马镇' },
|
||||
{ value: 15, name: '勐撒镇' },
|
||||
{ value: 12, name: '勐永镇' },
|
||||
{ value: 16, name: '孟定镇' },
|
||||
{ value: 8, name: '勐简乡' },
|
||||
{ value: 12, name: '贺派乡' },
|
||||
{ value: 10, name: '四排山乡' },
|
||||
{ value: 9, name: '芒洪乡' },
|
||||
{ value: 8, name: '大兴乡' },
|
||||
],
|
||||
option: {
|
||||
grid: {
|
||||
left: '5%',
|
||||
@ -28,9 +39,10 @@ const state = reactive({
|
||||
},
|
||||
},
|
||||
barStyle: {
|
||||
barWidth: 15,
|
||||
barWidth: 14,
|
||||
itemStyle: {
|
||||
borderRadius: [8, 8, 0, 0], // 设置柱子的圆角半径
|
||||
borderWidth: 14,
|
||||
borderRadius: [8, 8, 8, 8], // 设置柱子的圆角半径
|
||||
},
|
||||
color: {
|
||||
type: 'linear',
|
||||
@ -47,76 +59,48 @@ const state = reactive({
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
// name: '面积',
|
||||
// splitLine: {
|
||||
// show: false,
|
||||
// lineStyle: {
|
||||
// type: 'dashed',
|
||||
// color: '',
|
||||
// width: 1,
|
||||
// },
|
||||
// },
|
||||
axisTick: {
|
||||
splitLine: {
|
||||
show: false,
|
||||
alignWithLabel: false,
|
||||
interval: 'auto',
|
||||
inside: false,
|
||||
length: 5,
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
width: 1,
|
||||
color: 'rgba(28, 158, 222, 1)',
|
||||
type: 'dashed',
|
||||
color: '#E5E5E5',
|
||||
},
|
||||
},
|
||||
// axisLine: {
|
||||
// show: true,
|
||||
// lineStyle: {
|
||||
// type: 'solid',
|
||||
// width: 1,
|
||||
// // color: '#000',
|
||||
// },
|
||||
// },
|
||||
// axisLabel: {
|
||||
// margin: 8,
|
||||
// interval: 'auto',
|
||||
// rotate: 0,
|
||||
// fontSize: 10,
|
||||
// color: '#fff',
|
||||
// },
|
||||
axisLabel: {
|
||||
show: false,
|
||||
textStyle: {
|
||||
color: '#424242',
|
||||
},
|
||||
},
|
||||
show: false,
|
||||
axisLine: {
|
||||
show: true,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
// name: '面积(万亩)',
|
||||
data: ['耿马镇', '勐撒镇', '勐永镇', '孟定镇', '勐简乡', '贺派乡', '四排山乡', '芒洪乡', '大兴乡'],
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
// 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=',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
series: [
|
||||
{
|
||||
type: 'bar',
|
||||
// barWidth: '40%', // 设置柱的宽度
|
||||
// barMinHeight: 2, // 设置柱的最小高度
|
||||
// barGap: '20%', // 设置柱之间的间隙
|
||||
},
|
||||
],
|
||||
},
|
||||
data: [
|
||||
{ value: 20, name: '耿马镇' },
|
||||
{ value: 15, name: '勐撒镇' },
|
||||
{ value: 12, name: '勐永镇' },
|
||||
{ value: 16, name: '孟定镇' },
|
||||
{ value: 8, name: '勐简乡' },
|
||||
{ value: 12, name: '贺派乡' },
|
||||
{ value: 10, name: '四排山乡' },
|
||||
{ value: 9, name: '芒洪乡' },
|
||||
{ value: 8, name: '大兴乡' },
|
||||
],
|
||||
});
|
||||
</script>
|
||||
|
@ -44,7 +44,7 @@
|
||||
<div class="right-charts-item">
|
||||
<customBack top-title="各地农用地利用面积" :top-postion="'right'">
|
||||
<template #back>
|
||||
<landareaCharts></landareaCharts>
|
||||
<cake />
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
@ -60,6 +60,7 @@ import landCirculation from './components/landCirculation.vue';
|
||||
import landPlan from './components/landPlan.vue';
|
||||
import landPatrol from './components/landPatrol.vue';
|
||||
import LandAera from './components/LandAera.vue';
|
||||
import cake from './components/cake.vue';
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.data-home-index {
|
||||
|
Loading…
x
Reference in New Issue
Block a user