|
@@ -5,13 +5,14 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-const color = ['#005aff', '#f8b551', '#EF6666', '#3FA7FD']
|
|
|
+const color = ['#005aff', '#f8b551', '#EF6666', '#2fe30f','#fefefe']
|
|
|
import * as echarts from 'echarts';
|
|
|
import 'echarts-gl';
|
|
|
+
|
|
|
export default {
|
|
|
name: 'chart',
|
|
|
props: ['pieData'],
|
|
|
- data () {
|
|
|
+ data() {
|
|
|
return {
|
|
|
statusChart: null,
|
|
|
option: {}
|
|
@@ -19,7 +20,7 @@ export default {
|
|
|
},
|
|
|
watch: {
|
|
|
pieData: {
|
|
|
- handler (val) {
|
|
|
+ handler(val) {
|
|
|
if (val.length) {
|
|
|
this.$nextTick(() => {
|
|
|
this.initChart()
|
|
@@ -30,8 +31,9 @@ export default {
|
|
|
immediate: true
|
|
|
}
|
|
|
},
|
|
|
- mounted () {},
|
|
|
- beforeDestroy () {
|
|
|
+ mounted() {
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
if (!this.statusChart) {
|
|
|
return
|
|
|
}
|
|
@@ -41,19 +43,19 @@ export default {
|
|
|
},
|
|
|
methods: {
|
|
|
// 图表初始化
|
|
|
- initChart () {
|
|
|
+ initChart() {
|
|
|
if (!this.statusChart) {
|
|
|
this.statusChart = echarts.init(this.$refs.chart)
|
|
|
}
|
|
|
const pieData = this.pieData.map((item, index) => ({
|
|
|
...item,
|
|
|
itemStyle: {
|
|
|
- color: color[index]
|
|
|
+ color: color[index % color.length]
|
|
|
},
|
|
|
label: {
|
|
|
normal: {
|
|
|
show: true,
|
|
|
- color: color[index],
|
|
|
+ color: color[index % color.length],
|
|
|
formatter: [
|
|
|
'{b|{b}}',
|
|
|
'{c|{c}}{b|件}',
|
|
@@ -118,7 +120,7 @@ export default {
|
|
|
},
|
|
|
// 监听鼠标事件,实现饼图选中效果(单选),近似实现高亮(放大)效果。
|
|
|
// optionName是防止有多个图表进行定向option传递,单个图表可以不传,默认是opiton
|
|
|
- bindListen (myChart, optionName = 'option') {
|
|
|
+ bindListen(myChart, optionName = 'option') {
|
|
|
let selectedIndex = ''
|
|
|
let hoveredIndex = ''
|
|
|
// 监听点击事件,实现选中效果(单选)
|
|
@@ -126,36 +128,36 @@ export default {
|
|
|
// 从 option.series 中读取重新渲染扇形所需的参数,将是否选中取反。
|
|
|
const isSelected = !this[optionName].series[hoveredIndex].pieStatus.isSelected
|
|
|
const isHovered =
|
|
|
- this[optionName].series[params.seriesIndex].pieStatus.hovered
|
|
|
+ this[optionName].series[params.seriesIndex].pieStatus.hovered
|
|
|
const k = this[optionName].series[params.seriesIndex].pieStatus.k
|
|
|
const startRatio =
|
|
|
- this[optionName].series[params.seriesIndex].pieData.startRatio
|
|
|
+ this[optionName].series[params.seriesIndex].pieData.startRatio
|
|
|
const endRatio =
|
|
|
- this[optionName].series[params.seriesIndex].pieData.endRatio
|
|
|
+ this[optionName].series[params.seriesIndex].pieData.endRatio
|
|
|
// 如果之前选中过其他扇形,将其取消选中(对 option 更新)
|
|
|
if (selectedIndex !== '' && selectedIndex !== params.seriesIndex) {
|
|
|
this[optionName].series[
|
|
|
- selectedIndex
|
|
|
- ].parametricEquation = this.getParametricEquation(
|
|
|
- this[optionName].series[selectedIndex].pieData.startRatio,
|
|
|
- this[optionName].series[selectedIndex].pieData.endRatio,
|
|
|
- false,
|
|
|
- false,
|
|
|
- k,
|
|
|
- this[optionName].series[selectedIndex].pieData.value
|
|
|
+ selectedIndex
|
|
|
+ ].parametricEquation = this.getParametricEquation(
|
|
|
+ this[optionName].series[selectedIndex].pieData.startRatio,
|
|
|
+ this[optionName].series[selectedIndex].pieData.endRatio,
|
|
|
+ false,
|
|
|
+ false,
|
|
|
+ k,
|
|
|
+ this[optionName].series[selectedIndex].pieData.value
|
|
|
)
|
|
|
this[optionName].series[selectedIndex].pieStatus.selected = false
|
|
|
}
|
|
|
// 对当前点击的扇形,执行选中/取消选中操作(对 option 更新)
|
|
|
this[optionName].series[
|
|
|
- params.seriesIndex
|
|
|
- ].parametricEquation = this.getParametricEquation(
|
|
|
- startRatio,
|
|
|
- endRatio,
|
|
|
- isSelected,
|
|
|
- isHovered,
|
|
|
- k,
|
|
|
- this[optionName].series[params.seriesIndex].pieData.value
|
|
|
+ params.seriesIndex
|
|
|
+ ].parametricEquation = this.getParametricEquation(
|
|
|
+ startRatio,
|
|
|
+ endRatio,
|
|
|
+ isSelected,
|
|
|
+ isHovered,
|
|
|
+ k,
|
|
|
+ this[optionName].series[params.seriesIndex].pieData.value
|
|
|
)
|
|
|
this[optionName].series[params.seriesIndex].pieStatus.selected = isSelected
|
|
|
// 如果本次是选中操作,记录上次选中的扇形对应的系列号 seriesIndex
|
|
@@ -185,14 +187,14 @@ export default {
|
|
|
k = this[optionName].series[hoveredIndex].pieStatus.k
|
|
|
// 对当前点击的扇形,执行取消高亮操作(对 option 更新)
|
|
|
this[optionName].series[
|
|
|
- hoveredIndex
|
|
|
- ].parametricEquation = this.getParametricEquation(
|
|
|
- startRatio,
|
|
|
- endRatio,
|
|
|
- isSelected,
|
|
|
- isHovered,
|
|
|
- k,
|
|
|
- this[optionName].series[hoveredIndex].pieData.value
|
|
|
+ hoveredIndex
|
|
|
+ ].parametricEquation = this.getParametricEquation(
|
|
|
+ startRatio,
|
|
|
+ endRatio,
|
|
|
+ isSelected,
|
|
|
+ isHovered,
|
|
|
+ k,
|
|
|
+ this[optionName].series[hoveredIndex].pieData.value
|
|
|
)
|
|
|
this[optionName].series[hoveredIndex].pieStatus.hovered = isHovered
|
|
|
// 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空
|
|
@@ -200,30 +202,30 @@ export default {
|
|
|
}
|
|
|
// 如果触发 mouseover 的扇形不是透明圆环,将其高亮(对 option 更新)
|
|
|
if (
|
|
|
- params.seriesName !== 'mouseoutSeries' &&
|
|
|
- params.seriesName !== 'pie2d'
|
|
|
+ params.seriesName !== 'mouseoutSeries' &&
|
|
|
+ params.seriesName !== 'pie2d'
|
|
|
) {
|
|
|
// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。
|
|
|
isSelected = this[optionName].series[hoveredIndex].pieStatus.isSelected
|
|
|
isHovered = true
|
|
|
startRatio =
|
|
|
- this[optionName].series[params.seriesIndex].pieData.startRatio
|
|
|
+ this[optionName].series[params.seriesIndex].pieData.startRatio
|
|
|
endRatio = this[optionName].series[params.seriesIndex].pieData.endRatio
|
|
|
k = this[optionName].series[params.seriesIndex].pieStatus.k
|
|
|
// 对当前点击的扇形,执行高亮操作(对 option 更新)
|
|
|
this[optionName].series[
|
|
|
- params.seriesIndex
|
|
|
- ].parametricEquation = this.getParametricEquation(
|
|
|
- startRatio,
|
|
|
- endRatio,
|
|
|
- isSelected,
|
|
|
- isHovered,
|
|
|
- k,
|
|
|
- this[optionName].series[params.seriesIndex].pieData.value + 60
|
|
|
+ params.seriesIndex
|
|
|
+ ].parametricEquation = this.getParametricEquation(
|
|
|
+ startRatio,
|
|
|
+ endRatio,
|
|
|
+ isSelected,
|
|
|
+ isHovered,
|
|
|
+ k,
|
|
|
+ this[optionName].series[params.seriesIndex].pieData.value + 60
|
|
|
)
|
|
|
this[optionName].series[
|
|
|
- params.seriesIndex
|
|
|
- ].pieStatus.hovered = isHovered
|
|
|
+ params.seriesIndex
|
|
|
+ ].pieStatus.hovered = isHovered
|
|
|
// 记录上次高亮的扇形对应的系列号 seriesIndex
|
|
|
hoveredIndex = params.seriesIndex
|
|
|
}
|
|
@@ -233,19 +235,19 @@ export default {
|
|
|
})
|
|
|
},
|
|
|
// 自适应宽高
|
|
|
- changeSize () {
|
|
|
+ changeSize() {
|
|
|
this.statusChart.resize()
|
|
|
},
|
|
|
/**
|
|
|
- * 绘制3d图
|
|
|
- * @param pieData 总数据
|
|
|
- * @param internalDiameterRatio:透明的空心占比
|
|
|
- * @param distance 视角到主体的距离
|
|
|
- * @param alpha 旋转角度
|
|
|
- * @param pieHeight 立体的高度
|
|
|
- * @param opacity 饼或者环的透明度
|
|
|
- */
|
|
|
- getPie3D (pieData, internalDiameterRatio, distance, alpha, pieHeight, opacity = 1) {
|
|
|
+ * 绘制3d图
|
|
|
+ * @param pieData 总数据
|
|
|
+ * @param internalDiameterRatio:透明的空心占比
|
|
|
+ * @param distance 视角到主体的距离
|
|
|
+ * @param alpha 旋转角度
|
|
|
+ * @param pieHeight 立体的高度
|
|
|
+ * @param opacity 饼或者环的透明度
|
|
|
+ */
|
|
|
+ getPie3D(pieData, internalDiameterRatio, distance, alpha, pieHeight, opacity = 1) {
|
|
|
const series = []
|
|
|
let sumValue = 0
|
|
|
let startValue = 0
|
|
@@ -261,9 +263,9 @@ export default {
|
|
|
sumValue += pieData[i].value
|
|
|
const seriesItem = {
|
|
|
name:
|
|
|
- typeof pieData[i].name === 'undefined'
|
|
|
- ? `series${i}`
|
|
|
- : pieData[i].name,
|
|
|
+ typeof pieData[i].name === 'undefined'
|
|
|
+ ? `series${i}`
|
|
|
+ : pieData[i].name,
|
|
|
type: 'surface',
|
|
|
parametric: true,
|
|
|
wireframe: {
|
|
@@ -280,13 +282,13 @@ export default {
|
|
|
if (typeof pieData[i].itemStyle !== 'undefined') {
|
|
|
const itemStyle = {}
|
|
|
itemStyle.color =
|
|
|
- typeof pieData[i].itemStyle.color !== 'undefined'
|
|
|
- ? pieData[i].itemStyle.color
|
|
|
- : opacity
|
|
|
+ typeof pieData[i].itemStyle.color !== 'undefined'
|
|
|
+ ? pieData[i].itemStyle.color
|
|
|
+ : opacity
|
|
|
itemStyle.opacity =
|
|
|
- typeof pieData[i].itemStyle.opacity !== 'undefined'
|
|
|
- ? pieData[i].itemStyle.opacity
|
|
|
- : opacity
|
|
|
+ typeof pieData[i].itemStyle.opacity !== 'undefined'
|
|
|
+ ? pieData[i].itemStyle.opacity
|
|
|
+ : opacity
|
|
|
seriesItem.itemStyle = itemStyle
|
|
|
}
|
|
|
series.push(seriesItem)
|
|
@@ -301,12 +303,12 @@ export default {
|
|
|
series[i].pieData.startRatio = startValue / sumValue
|
|
|
series[i].pieData.endRatio = endValue / sumValue
|
|
|
series[i].parametricEquation = this.getParametricEquation(
|
|
|
- series[i].pieData.startRatio,
|
|
|
- series[i].pieData.endRatio,
|
|
|
- false,
|
|
|
- false,
|
|
|
- k,
|
|
|
- series[i].pieData.value
|
|
|
+ series[i].pieData.startRatio,
|
|
|
+ series[i].pieData.endRatio,
|
|
|
+ false,
|
|
|
+ false,
|
|
|
+ k,
|
|
|
+ series[i].pieData.value
|
|
|
)
|
|
|
startValue = endValue
|
|
|
const bfb = this.fomatFloat(series[i].pieData.value / sumValue, 4)
|
|
@@ -383,7 +385,7 @@ export default {
|
|
|
/**
|
|
|
* 生成扇形的曲面参数方程,用于 series-surface.parametricEquation
|
|
|
*/
|
|
|
- getParametricEquation (startRatio, endRatio, isSelected, isHovered, k, h) {
|
|
|
+ getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
|
|
|
// 计算
|
|
|
const midRatio = (startRatio + endRatio) / 2
|
|
|
const startRadian = startRatio * Math.PI * 2
|
|
@@ -415,13 +417,13 @@ export default {
|
|
|
x: function (u, v) {
|
|
|
if (u < startRadian) {
|
|
|
return (
|
|
|
- offsetX +
|
|
|
- Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ offsetX +
|
|
|
+ Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
)
|
|
|
}
|
|
|
if (u > endRadian) {
|
|
|
return (
|
|
|
- offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
)
|
|
|
}
|
|
|
return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate
|
|
@@ -429,13 +431,13 @@ export default {
|
|
|
y: function (u, v) {
|
|
|
if (u < startRadian) {
|
|
|
return (
|
|
|
- offsetY +
|
|
|
- Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ offsetY +
|
|
|
+ Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
)
|
|
|
}
|
|
|
if (u > endRadian) {
|
|
|
return (
|
|
|
- offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
)
|
|
|
}
|
|
|
return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate
|
|
@@ -455,7 +457,7 @@ export default {
|
|
|
/**
|
|
|
* 获取3d丙图的最高扇区的高度
|
|
|
*/
|
|
|
- getHeight3D (series, height) {
|
|
|
+ getHeight3D(series, height) {
|
|
|
series.sort((a, b) => {
|
|
|
return b.pieData.value - a.pieData.value
|
|
|
})
|
|
@@ -465,7 +467,7 @@ export default {
|
|
|
/**
|
|
|
* 格式化浮点数
|
|
|
*/
|
|
|
- fomatFloat (num, n) {
|
|
|
+ fomatFloat(num, n) {
|
|
|
let f = parseFloat(num)
|
|
|
if (isNaN(f)) {
|
|
|
return false
|