console
const data = [
{
name: 'A部门',
value: 150,
itemStyle: { color: 'red' }
},
{
name: 'B部门',
value: 450,
itemStyle: { color: 'green' },
selected: false
},
{
name: 'C部门',
value: 750,
itemStyle: { color: 'blue' }
}
]
function getSeries(data, k) {
let sum = 0
const series = data.map(i => {
sum += i.value
return {
type: 'surface',
name: i.name,
parametric: true,
value: i.value,
wireframe: { show: false },
itemStyle: { ...i.itemStyle },
pieData: {...i, k},
zlevel: 1
}
})
let begin = 0
let end = 0
for (const item of series) {
end = begin + item.value
const startRatio = begin / sum
const endRatio = end / sum
item.pieData.startRatio = startRatio
item.pieData.endRatio = endRatio
item.parametricEquation = getEq(item)
begin = end
}
const temp = data.map(i => {
return {
...i,
itemStyle: { ...i.itemStyle, color: 'rgba(255, 0, 0, 0)'}
}
})
series.push({
type: 'pie',
startAngle: 10,
clockwise: false,
data: temp,
labelLine: { show: true, lineStyle: { color: 'black' } },
center: ['50%', '54%'],
radius: [0, '50%'],
z: 0
})
return series
}
function getEq(item) {
const { startRatio, endRatio, isSelected, k } = item.pieData
const s = startRatio * 2 * Math.PI
const e = endRatio * 2 * Math.PI
const h = isSelected ? 2 : 1
return {
u: {
min: -Math.PI,
max: 3 * Math.PI,
step: Math.PI / 32
},
v: {
min: 0,
max: 2 * Math.PI,
step: Math.PI / 32
},
x: function(u, v) {
if (u < s) {
return Math.cos(s) * (1 + Math.cos(v) * k)
} else if (u > e) {
return Math.cos(e) * (1 + Math.cos(v) * k)
}
return Math.cos(u) * (1 + Math.cos(v) * k)
},
y: function(u, v) {
if (u < s) {
return Math.sin(s) * (1 + Math.cos(v) * k)
} else if (u > e) {
return Math.sin(e) * (1 + Math.cos(v) * k)
}
return Math.sin(u) * (1 + Math.cos(v) * k)
},
z: function(u, v) {
if (u < -Math.PI / 2) {
return Math.sin(u)
} else if (u > Math.PI * 2.5) {
return Math.sin(u)
}
return Math.sin(v) > 0 ? h : -1
}
}
}
const series = getSeries(data, 1/3)
// console.log('===series', series)
const option = {
grid3D: {
show: false,
boxHeight: 20,
viewControl: {
alpha: 40,
beta: 0,
distance: 250,
autoRotate: false,
rotateSensitivity: 0,
zoomSensitivity: 0,
panSensitivity: 0
}
},
xAxis3D: { min: -1, max: 1 },
yAxis3D: { min: -1, max: 1 },
zAxis3D: { min: -1, max: 1 },
series
}
const dom = document.querySelector('#chart')
const chart = echarts.init(dom)
chart.setOption(option)
let hoverIndex = -1
chart.on('mouseover', (params) => {
// console.log('hover', params)
const subtype = params.componentSubType
let idx = -1
if (subtype === 'surface') {
idx = params.seriesIndex
} else if (subtype === 'pie') {
idx = params.dataIndex
}
if (hoverIndex === idx) {
return
}
if (hoverIndex !== -1) {
const prevSerie = series[hoverIndex]
prevSerie.pieData.isSelected = false
prevSerie.parametricEquation = getEq(prevSerie)
series.splice(hoverIndex,1, prevSerie)
}
hoverIndex = idx
const serie = series[idx]
if (serie) {
serie.pieData = { ...serie.pieData, isSelected: true }
serie.parametricEquation = getEq(serie)
const tmpList = [...series]
tmpList.splice(idx, 1, serie)
chart.setOption({
series: tmpList
})
}
})
chart.on('globalout', () => {
if (hoverIndex !== -1) {
const serie = series[hoverIndex]
serie.pieData = { ...serie.pieData, isSelected: false }
const list = [...series]
list.splice(hoverIndex, 1, serie)
chart.setOption({
series: list
})
}
})
<div id="chart"></div>
#chart {
width: 300px;
height:300px;
border: 1px solid red;
}