
页面
<template>
<div id="myChart" ref="myChart" class="pie-chart"></div>
</template>
<script lang='ts' setup>
import { getPie3D, getParametricEquation } from "../utils/largeScreen"
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
import * as echarts from "echarts";
onMounted(() => {
intit()
})
function intit() {
const charEle = document.getElementById('myChart') as HTMLElement;
const echarts1 = echarts.init(charEle);
const optionData = [
{
value: 1089, name: '配发'
},
{
value: 735, name: '销毁'
},
{
value: 580, name: '借用'
},
{
value: 484, name: '维修'
},
{
value: 300, name: '其他'
}
]
const option = getPie3D(optionData, 0.8, 240, 180, 50, 0.6)
echarts1.setOption(option)
option.series.push({
backgroundColor: '#fff',
type: 'pie',
label: {
show: false
},
startAngle: -20,
clockwise: false,
avoidLabelOverlap: false,
radius: ['20%', '50%'],
center: ['50%', '50%'],
data: optionData,
itemStyle: {
opacity: 0,
color: (params: any) => {
let colorList = [
{
colorStart: '#0981FF',
colorEnd: '#83A1FF'
},
{
colorStart: '#63BBF0',
colorEnd: '#071829'
},
{
colorStart: '#1A171C',
colorEnd: '#DEC6FF'
},
{
colorStart: '#161510',
colorEnd: '#FFF189'
}, {
colorStart: '#0E1111',
colorEnd: '#FF9090'
}
]
return new echarts.graphic.LinearGradient(1, 0, 0, 0, [{
offset: 0,
color: colorList[params.dataIndex]['colorStart']
}, {
offset: 1,
color: colorList[params.dataIndex]['colorEnd']
}])
}
},
labelLine: {
show: false
},
})
echarts1.setOption(option)
window.onresize = function () {
echarts1.resize()
}
}
</script>
<style lang='less' scoped>
.pie-chart {
width: 100%;
height: 100%;
}
</style>

- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
largeScreen.ts
const getPie3D = (pieData: any[], internalDiameterRatio: number, distance: any, alpha: any, pieHeight: any, opacity =0.8) => {
const series = []
let sumValue = 0
let startValue = 0
let endValue = 0
let legendData = []
let legendBfb: { name: any; value: string | boolean }[] = []
const k = 1 - internalDiameterRatio
pieData.sort((a: { value: number }, b: { value: number }) => {
return b.value - a.value
})
for (let i = 0; i < pieData.length; i++) {
console.log(pieData[i], "pieData[i]")
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: k
},
center: ['50%', '50%']
}
console.log(pieData[i].itemStyle, "pieData[i].itemStyle")
if (typeof pieData[i].itemStyle !== 'undefined') {
console.log(pieData[i].itemStyle, "pieData[i].itemStyle")
const itemStyle = {}
itemStyle.color = typeof pieData[i].itemStyle.color !== 'undefined'
? pieData[i].itemStyle.color
: opacity
itemStyle.opacity =
typeof pieData[i].itemStyle.opacity !== 'undefined'
? pieData[i].itemStyle.opacity
: opacity
seriesItem.itemStyle = itemStyle
}
series.push(seriesItem)
}
legendData = []
legendBfb = []
for (let i = 0; i < series.length; i++) {
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,
series[i].pieData.value
)
startValue = endValue
const bfb = fomatFloat(series[i].pieData.value / sumValue, 4)
legendData.push({
name: series[i].name,
value: bfb
})
legendBfb.push({
name: series[i].name,
value: bfb
})
}
const boxHeight = getHeight3D(series, pieHeight)
const option = {
color: ["#3747B0", "#63BBF0", "#DFC6FF", "#FFD156", "#AD6565"],
legend: {
left: '70%',
top: 'middle',
orient: 'vertical',
itemWidth: 8,
itemHeight: 8,
textStyle: {
color: "#fff",
fontSize:fontSize(0.14),
fontFamily: "DINAlternateBold"
},
show: true,
data: legendData,
itemGap: 10,
formatter: function (param: any) {
const item = legendBfb.filter(item => item.name === param)[0]
const bfs = fomatFloat(item.value * 100, 2) + '%'
return `${item.name} ${bfs}`
},
},
labelLine: {
show: false,
},
label: {
show: false,
position: 'outside',
formatter: '{b} \n{c} {d}%'
},
tooltip: {
show: false,
},
xAxis3D: {
min: -0.7,
max: 1
},
yAxis3D: {
min: -0.7,
max: 1
},
zAxis3D: {
min: -0.7,
max: 1
},
grid3D: {
show: false,
boxWidth: 100,
boxHeight: boxHeight,
viewControl: {
alpha,
distance,
rotateSensitivity: 0,
zoomSensitivity: 0,
panSensitivity: 0,
autoRotate: false
}
},
series: series
}
return option
}
const getParametricEquation = (startRatio: number, endRatio: number, isSelected: boolean, isHovered: boolean, k: number, h: number) => {
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 = isSelected ? Math.cos(midRadian) * 0.1 : 0
const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0
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: function (u: number, v: number) {
if (u < startRadian) {
return (
offsetX +
Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
)
}
if (u > endRadian) {
return (
offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
)
}
return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate
},
y: function (u: number, v: number) {
if (u < startRadian) {
return (
offsetY +
Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
)
}
if (u > endRadian) {
return (
offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
)
}
return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate
},
z: function (u: number, v: number) {
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
}
}
}
const getHeight3D = (series: any[], height: number) => {
series.sort((a: { pieData: { value: number } }, b: { pieData: { value: number } }) => {
return b.pieData.value - a.pieData.value
})
return (height * 25) / series[0].pieData.value
}
const fomatFloat = (num: any, n: number) => {
let f = parseFloat(num)
if (isNaN(f)) {
return false
}
f = Math.round(num * Math.pow(10, n)) / Math.pow(10, n)
let s = f.toString()
let rs = s.indexOf('.')
if (rs < 0) {
rs = s.length
s += '.'
}
while (s.length <= rs + n) {
s += '0'
}
return s
}
function fontSize(res: number) {
let clientWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
if (!clientWidth) return;
let fontSize = 100 * (clientWidth / 3840);
return res * fontSize;
}
export { getPie3D, getParametricEquation }

- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267