使用echarts绘制火焰图

介绍

火焰图常用于性能分析中,显示某个函数堆栈的耗时情况,一般火焰图区块越大,表示耗时越高,越有可能是性能热点,如何读懂火焰图?

绘制原理

echarts官方是没有火焰图类型的图表的,但是可以通过 echarts的custom类型来绘制火焰图;
在这里插入图片描述
火焰图本质上就是一些长方体区块的堆叠,因此我们只需要计算好每个方块的左下角坐标,以及每个方块的宽高,就可以把火焰图绘制出来

主要用到了 custom系列的

  • renderItem函数,用于自定义图形绘制,对series中的每一个数据项都会应用一次
  • api.value,用于在renderItem中获取设置的series中的数据
  • api,coord函数,用于在renderItem函数中计算某个方块的坐标以及宽高

详细文档参考官方链接https://echarts.apache.org/zh/option.html#series-custom.renderItem

绘制

以下是关键部分代码,也就是renderItem函数

/*
在我的原始数据中,记录了每个函数的调用起始时间偏移量(可以理解为函数调用相对于基准时间的差值),调用耗时,堆栈深度,以及其他数据
绘制过程中主要就是使用 时间偏移量计算在图表中的x坐标,用深度计算y坐标,用耗时计算区块的宽度, 
设置的数据格式是
 series:{
 	data:[
 		[offset,timeSpan, depth,xxx],
 		[offset,timeSpan, depth,xxx],
 		[offset,timeSpan, depth,xxx]
 	]
 }
*/
renderItem(params,api)
{
	//整个流程是在vue组件中的,所以这里的this指向的是当前vue组件
	//这里使用maxDepth是因为我绘制的火焰图是倒过来的,深度小的在上面,深度大的在下面
	const maxDepth = this.maxDepth; 
	const minDepth = this.minDepth; //minDepth其实没用到,不写也可以
	const offset = api.value(0);
	const timeSpan = api.value(1);
	const depth = api.value(2);
	
	const start = api.coord([offset, maxDepth-depth]); //y坐标倒一下
	const end = api.coord([offset+timeSpan, maxDepth-depth]);
	const normalSize = api.size([1, 1]); //获取单位长度
	const height = normalSize[1];
	const width= end[0]-start[0];
	//如果数据量太大,可以把一些宽度过小的图元过滤掉,减小压力,当然,也可以在数据源进行过滤
	if(width<1) 
	{
		return
	}
	//这里创建一个长方体图元
	let rectShape = echarts.graphic.clipRectByRect({
		x: start[0],
		y: start[1]-height/2,
		width: width,
		height: normalSize[1],
	}, {
		x: params.coordSys.x,
		y: params.coordSys.y,
		width: params.coordSys.width,
		height: params.coordSys.height
	});


	//var style={ //这里可以自定义填充颜色
	//	fill: option.color[parseInt(width%option.color.length)],
	//}
	//if(depth<nowData.minDepth)
	//{
	//	style.fill= '#808080';
	//}
	//if(depth === criterion.depth && offset === criterion.offset)
	//{
	//	style.stroke='yellow'; //边框颜色以及线的属性也是可以配置的
	//	style.lineWidth=2;
	//}

	return rectShape && {
		type: 'rect',
		shape: rectShape,
		//style: api.style(style),
	};
},

缩放

火焰图是可以交互的,点击某个区块可以进行缩放,这个可以使用echarts自带的dispatchAction来发送dataZoom事件实现,通过设置 dataZoom的startValue和endValue进行缩放

this.chartInstance.dispatchAction(
{
	type      : 'dataZoom',
	startValue: dataItem.offset,
	endValue  : dataItem.offset+dataItem.timeSpan,
});

需要注意的是,在缩放后,可能会出现边缘有部分区块是没有被完全过滤掉的,正常情况下不会有问题,但是如果你使用动态计算火焰图区块上名字的宽度的话,就会出现问题,
可以在renderItem中通过不绘制的方法进行手动过滤

 if(offset>=endValue || offset+timeSpan<=startValue)
 {
    
 	return}

动态计算区块中函数名的宽度的方法可以查看 js获取字符串像素宽度,通过动态计算字符串宽度,在 图表的 series-label-formatter中动态显示字符串

series:{
	label:{
		formatter: function(param){}
	}
}

效果

除了配色辣眼睛外,其他的功能都实现了,配色算法研究中。。。
在这里插入图片描述

有什么问题欢迎评论留言一起探讨!

要在Vue中使用Echarts绘制迁徙,你需要完成以下步骤: 1. 安装echarts:在终端中运行`npm install echarts --save`,或者使用yarn安装,即运行`yarn add echarts` 2. 在Vue组件中引入echarts:在你需要使用echarts的组件中,导入echarts模块,例如: ``` import echarts from 'echarts' ``` 3. 在Vue组件中创建一个div元素作为echarts表的容器,例如: ``` <template> <div class="chart-container" ref="chart"></div> </template> ``` 4. 在Vue组件中编写echarts配置项,例如: ``` <script> import echarts from 'echarts' export default { name: 'MigrationChart', data() { return { chart: null } }, mounted() { this.chart = echarts.init(this.$refs.chart) const option = { ... } this.chart.setOption(option) } } </script> ``` 5. 在echarts配置项中指定迁徙的数据和样式,例如: ``` const option = { title: { text: '迁徙' }, tooltip: {}, visualMap: { min: 0, max: 1000, seriesIndex: 1, inRange: { color: ['#D0EEFF', '#0092F6'] } }, series: [{ type: 'map', mapType: 'world', roam: true, emphasis: { label: { show: true } }, data: [{ name: 'China', value: 100 }, { name: 'United States', value: 500 }] }, { type: 'lines', zlevel: 2, symbol: ['none', 'arrow'], symbolSize: 10, effect: { show: true, period: 6, trailLength: 0, symbol: 'arrow', symbolSize: 12 }, lineStyle: { normal: { color: '#a6c84c', width: 0, curveness: 0.2 } }, data: [{ fromName: 'China', toName: 'United States', coords: [ [116.407526, 39.90403], [-98.5795, 39.828175] ] }] }] } ``` 以上就是在Vue中使用echarts绘制迁徙的基本步骤,你可以根据自己的实际需求来修改代码。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值