前言:

echarts的vue.js组件是vue-echarts。基于此封装可以直接调用其提供的API,更加方便。

特别说明,本文使用的echarts和vue-echarts均为4.x版本。

java后台封装echarts echarts封装新类_封装

4.x版本的图表默认尺寸为600px * 400px,如果要设置响应式尺寸需要使用类选择器。

查看代码

.echarts {
  width: 100%;
  height: 100%;
}

你也可以使用5.x版本,只是在vue2.x下使用需要注意一些事情。详见文档

echarts图表封装

  以往的需求中图表可能只在项目中出现一次,但慢慢的出现了重复性的图表,为了更加快捷的图表生成,所以有必要进行一次封装。

  1. main.js中将echarts按需引入。
import VueECharts from 'vue-echarts'
// 按需引入 ECharts 各模块
import 'echarts/lib/component/grid'
import 'echarts/lib/component/title'
import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/legend'
import 'echarts/lib/chart/pie'
import 'echarts/lib/chart/scatter'
import 'echarts/lib/chart/effectScatter'
import 'echarts/lib/component/toolbox'
import 'echarts/lib/component/dataZoom'
import 'echarts/lib/component/markPoint'
  1. 手动创建单位转换方法供echarts中文字使用。
const setFontSize = (res) => {
	const clientWidth = document.body.clientWidth
	// 设计稿是1920标准;那么1px等于100vw / 1920
	const fontSize = clientWidth / 1920
	return res * fontSize
}

Vue.prototype.$setFontSize = setFontSize;
  1. components目录下新建PieChart/PieChart.vue文件。
<template>
	<vue-echarts ref="chartSample" :options="pieChartOptions" />
</template>

<script>
	import domResizeListener from "element-resize-detector";

	export default {
		name: "PieChart",
		props: {
			// 这里粒度可自定义,比如大多数配置相同,仅formatter不同,
			// 父组件传入业务数据,对应饼图配置中的series[0].data
			acceptOptions: {
				type: Array,
				required: true,
				default: () => [],
			}
		},

		watch: {
			acceptOptions: {
				deep: true,
				handler() {
					this.mergeChartOptions()
				}
			}
		},

		data() {
			return {
				// 这里编写通用的options属性
				pieChartOptions: {
					legend: {
						orient: 'vertical',
						right: 'right',
						textStyle: {
							color: '#c5ebf5',
							fontSize: this.$setFontSize(12)
						}
					},
					tooltip: {
						trigger: 'item',
						formatter: '{b} : {c} ({d}%)'
					},
					toolbox: {
						feature: {
							saveAsImage: {
								iconStyle: {
									borderColor: '#ffffff',
									borderWidth: 3
								},
								emphasis: {
									iconStyle: {
										borderColor: '#ffffff'
									}
								}
							}
						}
					},
					series: [{
						type: 'pie',
						radius: '55%',
						center: ['35%', '45%'],
						data: [],
						label: {
							textStyle: {
								color: '#ffffff',
								fontSize: this.$setFontSize(16),
								fontWeight: 'bolder'
							}
						},
						emphasis: {
							itemStyle: {
								shadowBlur: 10,
								shadowOffsetX: 0,
								shadowColor: 'rgba(0, 0, 0, 0.5)'
							}
						}
					}]
				}
			}
		},

		mounted() {
			// 当窗口大小变化时图表重绘
			this.openWindowListener()
			// 监听图表DOM元素尺寸,当变化时图表重绘
			this.openDomListener()
			
			// ......其他逻辑,比如轮询
		},

		methods: {
			mergeChartOptions() {
				// 这里赋值需要变化的options属性
				this.pieChartOptions.series[0].data[0] = this.acceptOptions
				// mergeOptions()方式,实际是调用了echarts的setOption()方法。
				// 注意如果为options重新绑定对象,则默认不立即合并更新图表。
				// 		如果只修改options中的属性,则默认立即合并更新图表。
				// 		所以如果图表不更新可改false为true。
				this.$refs.chartSample.mergeOption(this.acceptOptions, false)
			},
			openWindowListener() {
				window.addEventListener("resize", this.$ref.chartSample.resize());
			},
			openDomListener() {
				const echartsInstance = domResizeListener({
					strategy: "scroll",
					callOnAdd: true,
				});
				echartsInstance.listenTo(this.$el, () => {
					this.$ref.chartSample.resize();
				});
			}
		},
	};
</script>

<style scoped="scoped">
	/* 根据父盒子自适应大小 */
	.echarts {
		width: 100%;
		height: 100%;
	}
</style>

  以上已经尽可能的抽离了公共部分,无需编写重复代码。只要能将通用options编写好,剩下的只需要传入修改的部分即可。

 

屏幕适配

  以前的屏幕适配大多使用flexible完成,但上次做项目时发现仓库中多了这样一段话。

java后台封装echarts echarts封装新类_封装_02

所以这里使用postcss-px-to-viewport这个插件帮助我们进行单位的转换。使用前要进行配置。

java后台封装echarts echarts封装新类_chrome_03

该说不说viewport单位就是香!开发中最直接的好处就是无需关心单位,px一把梭,自动适配不同分辨率的屏幕,1080P,2k,4k下显示效果都一致!

查看不同分辨率下显示效果可以在开发者工具中自定义尺寸实现。如下示例。

java后台封装echarts echarts封装新类_java后台封装echarts_04

特别说明:有些地方渲染时单位并没有被转为viewport单位。比如图表的fontSize,这时就需要手动编写函数转换单位了。

lineChart: {
          textStyle: {
            fontSize: this.setFontSize(14)
          }
}
setFontSize (res) {
        const clientWidth = document.body.clientWidth
        // 设计稿是1920标准;那么1px等于100vw / 1920
        const fontSize = clientWidth / 1920
        return res * fontSize
}

 

3D OR 全景

  3D组件是界面中十分重要的组成元素,市面上的相关产品让人感觉多如牛毛。物联网行业内应用尤其广泛,优诺科技是我接触到的发展最为前沿的企业。

java后台封装echarts echarts封装新类_chrome_05

从可视化大屏到元宇宙展厅,可谓是相当齐全了,但最终也没有使用此产品,原因也很简单:贵!对于小厂来说,业务量不大,却要为一个功能付昂贵的款项,肯定没戏。所以这里列举3D组件的替代方式。

  一:制作全景图(https://www.720yun.com/可手机完成)

  二:俯瞰图做底图(航拍获得或客户方提供)

  三:3D生成手机软件

  四:3D生成PC软件(pano2vr,krpano)

 

报警提示音

  这可能也是一个常见的需求,比如某设备故障,客户端要有报警提示音。但由于chrome的规定不能在未操作文档前播放音频。详情可以翻翻chrome文档。

  这里比较建议采用的是配置一个按钮,引导用户点击一下文档,这样就避免了上述的情况,等后续用户访问站点次数多了,满足了chrome自动播放音频的条件,就可以不用点击文档也能播放音频了。