Echarts实现自定义图标——风向图

在这里插入图片描述
上图用了两种模式表示风向图,第一种是自定义系列,第二种使用了折线图,给折线图添加自定义图标。
两者的区别在于给options.series设置不同的type值,如下图:
在这里插入图片描述
那么我们来一步步实现代码,先创建一个HTML文件,引入echarts.js

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.bootcdn.net/ajax/libs/echarts/4.0.4/echarts.min.js"></script>
	</head>
	<body>
		<div id="my-echarts" style="width: 1500px;height:1000px;margin-top: 60px;"></div>
	</body>
</html>

接着在script标签里面写代码

		//初始化实例对象
		let myChart = echarts.init(document.querySelector('#my-echarts'));
		
		//定义一个风向的数据用来做自定义数据,windDirection字段表示风向
		let windDirectionData = [{
				time: "2017-06-27T11:00:00.000Z",
				windDirection: 0,
			},
			{
				time: "2017-06-27T12:30:00.000Z",
				windDirection: 1,
			},
			{
				time: "2017-06-27T14:00:00.000Z",
				windDirection: 122,
			},
			{
				time: "2017-06-27T15:30:00.000Z",
				windDirection: 45,
			},
			{
				time: "2017-06-27T17:00:00.000Z",
				windDirection: 60,
			},
			{
				time: "2017-06-27T18:30:00.000Z",
				windDirection: 70,
			},
			{
				time: "2017-06-27T20:00:00.000Z",
				windDirection: 80,
			},
			{
				time: "2017-06-27T21:30:00.000Z",
				windDirection: 90,
			},
			{
				time: "2017-06-27T23:00:00.000Z",
				windDirection: 120,
			},
			{
				time: "2017-06-28T00:30:00.000Z",
				windDirection: 121,
			},
			{
				time: "2017-06-28T02:00:00.000Z",
				windDirection: 122,
			},
			{
				time: "2017-06-28T03:30:00.000Z",
				windDirection: 123,
			},
			{
				time: "2017-06-28T05:00:00.000Z",
				windDirection: 124,
			},
			{
				time: "2017-06-28T06:30:00.000Z",
				windDirection: 105,
			},
			{
				time: "2017-06-28T08:00:00.000Z",
				windDirection: 95,
			},
			{
				time: "2017-06-28T09:30:00.000Z",
				windDirection: 85,
			},
			{
				time: "2017-06-28T11:00:00.000Z",
				windDirection: 85,
			},
			{
				time: "2017-06-28T12:30:00.000Z",
				windDirection: 85,
			},
			{
				time: "2017-06-28T14:00:00.000Z",
				windDirection: 59,
			},
			{
				time: "2017-06-28T15:30:00.000Z",
				windDirection: 105,
			},
			{
				time: "2017-06-28T17:00:00.000Z",
				windDirection: 115,
			},
			{
				time: "2017-06-28T18:30:00.000Z",
				windDirection: 152,
			},
			{
				time: "2017-06-28T20:00:00.000Z",
				windDirection: 300,
			},
			{
				time: "2017-06-28T21:30:00.000Z",
				windDirection: 213,
			},
		]
		//再定义一个数据,用来给折线图做数据使用
		const winddirs = ["0", "20", "40", "80", "66", "102", "33", "110", "112", "120", "120", "129", "120", "160", "156",
			"136", "126", "115", "126", "46", "76", "78", "27", "119"
		]
		
		//循环windDirectionData新增一个winddir字段,winddir是用来渲染自定义图标旋转弧度的,这里不能使用12,26,300这样的旋转角度值,
		//必须要把服务器返回的角度值转化为弧度值才可以使图标旋转到正确的角度。
		const timeArr = [] //用来做x轴的数据
		windDirectionData.forEach(val=> {
			val['winddir'] = (-Math.PI / 180) * val.windDirection; //自定义图标旋转的弧度值
			timeArr.push(echarts.format.formatTime(
				'hh:mm',
				val.time
			))
		})
		//处理下自定义图标的数据,可以看到,自定义图标生成了一个数组,我们把数组的第一项:180,固定写死,那么我们的自定义
		//图标就会在y轴对应的180值位置,排成一排,这个值可以随便改,根据自己的需求来,数组的第二项winddir字段是我们要渲染
		//的图标旋转弧度值,第三项windDirection是我们在图表展示的提示信息。
		const customData = windDirectionData.map(function(entry, index) {
			return [index, 180, entry.winddir, entry.windDirection];
		});

		const arrowSize = 18; //定义下图标的大小
		//写一个函数处理自定义图标的数据
		const renderArrow = function(param, api) {
			const point = api.coord([api.value(0), api.value(1)]); //这里表示自定义图标在坐标系里面的位置,包含y,x轴
			//我这里使用path,svg图标,大家可以自由搭配,svg图标从阿里图标库里面下载的。
			return {
				type: 'path',
				shape: {
					pathData: 'M688.64 995.2H341.12a53.12 53.12 0 0 1-53.12-52.48V520.96H45.44a32 32 0 0 1-30.08-21.12 30.72 30.72 0 0 1 8.32-35.2L512 21.76a32 32 0 0 1 44.16 0l442.88 442.24a33.92 33.92 0 0 1 7.04 35.84 32 32 0 0 1-30.08 19.84h-215.68v402.56a71.68 71.68 0 0 1-71.68 72.96z m-336-64h336a7.04 7.04 0 0 0 7.04-7.04V488.32a32 32 0 0 1 32.64-32h172.16L535.04 90.88 128 456.32h192a32 32 0 0 1 32.64 32z',
					x: -arrowSize / 2,
					y: -arrowSize / 2,
					width: arrowSize,
					height: arrowSize
				},				
				//这里调用echarts内部方法生成图标旋转角度,
				//具体参考:https://echarts.apache.org/zh/option.html#series-custom.renderItem
				rotation: api.value(2), 
				position: point, //在图表里面的坐标
				style: {
					stroke: '#55aaff',
					lineWidth: 1
				}
			};
		};
		let option = {
			title: {
				text: "风向图",
				left: 'center',
				textStyle: {
					color: '#000',
					fontSize: 24,
				},
			},
			color: ["#3399FF", "#7BB31A", "#00FFFF", "#FF4C3B"],
			grid: {
				show: true,
				top: '5%',
				bottom: '19%',
				left: '6%',
				right: '4%'
			},
			legend: { //系列标记
				show: true,
				top: '20px',
				zlevel: 2,
				right: '30px',
			},
			tooltip: {
				trigger: 'axis',
				formatter: function(params) {
					return [
						params[0].axisValue,
						'风向:' + params[0].data[3] + '°',
					].join('<br>');
				}
			},
			xAxis: {
				type: "category",
				name: "(h)",
				boundaryGap: true, //默认,坐标轴留白策略
				axisLine: {
					show: false
				},
				splitLine: {
					show: false
				},
				axisTick: {
					show: false,
					alignWithLabel: true
				},
				data: timeArr
			},
			yAxis: {
				axisLine: {
					show: false
				},
				splitLine: {
					show: true,
					lineStyle: {
						type: 'dashed',
						color: 'rgba(33,148,246,0.2)'
					}
				},
				max: 200,
				axisTick: {
					show: false
				},
			},
			series: [{
					name: '风向1',
					type: 'custom',
					renderItem: renderArrow,
					data: customData,
					z: 10
				},
				{
					name: '风向2',
					type: 'line',
					symbol: 'circle',
					symbolSize: 7,
					data: getWindSeries(winddirs),
				}
			]
		};
		function getWindSeries(winddirs) {
			//这里是给折线图加上自定义的风向图标
			let windSeries = [];
			for (let i = 0; i < winddirs.length; i++) {
				windSeries.push({
					value: parseFloat(winddirs[i]),
					symbol: 'path://M688.64 995.2H341.12a53.12 53.12 0 0 1-53.12-52.48V520.96H45.44a32 32 0 0 1-30.08-21.12 30.72 30.72 0 0 1 8.32-35.2L512 21.76a32 32 0 0 1 44.16 0l442.88 442.24a33.92 33.92 0 0 1 7.04 35.84 32 32 0 0 1-30.08 19.84h-215.68v402.56a71.68 71.68 0 0 1-71.68 72.96z m-336-64h336a7.04 7.04 0 0 0 7.04-7.04V488.32a32 32 0 0 1 32.64-32h172.16L535.04 90.88 128 456.32h192a32 32 0 0 1 32.64 32z',
					symbolSize: 18,
					symbolRotate: -parseFloat(winddirs[i]),
					itemStyle: {
						color: '#f00'
					}
				});
			}
			return windSeries;
		}
		myChart.setOption(option);
		
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值