百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

特斯拉是如何使用 Apache ECharts 的?

bigegpt 2025-02-15 14:35 8 浏览

在ApacheCon Asia 2021大会的“数据可视化论坛”上,特斯拉 BI 团队全栈开发工程师孟繁超(Makefile 君)发表了题为“ECharts 的乐趣:我们在特斯拉使用它的经验”的演讲。本文是这次演讲的内容总结。

大家好,我是孟繁超,在网上的昵称是 Makefile 君,目前在上海特斯拉 BI 团队担任全栈开发工程师。我平时主要负责相关业务报表的研发还有架构方面的工作。本次分享为大家带来我们在特斯拉中国使用Apache ECharts改善业务报表系统的一些经验。

我的分享分为两部分,第一部分是介绍我们报表系统是如何选型,以及如何决定使用 ECharts 作为主图表的经验;另外一部分是类似于一个 Workshop 形式,我们会提供一些非常简单的例子,让各位只要会基本的 Python 就可以很快上手做出一个动态的可视化图表。

下面我们正式开始分享。

背景

BI 团队会有非常多的报表需求,我们最开始的时候也是基于 Apache 旗下的另一个项目,也是非常有名的叫Superset,号称开源的 Tableau。不过我们当时做得比较早,是基于它 0.2X 版本分叉出来一种企业化定制的版本。

但我们发现它有一些问题,因为我们有定制,会导致它和主分支有一些偏移,并且在 0.3x 版本的时候有一些非常大的改动,我们很难无缝合并回主分支。同时我们在使用 Superset 时发现,虽然它早期的图表虽然非常多,但相对还是比较单一的,同时一些定制化的需求发现它确实无法满足。我们还遇到了一些问题,比如一些图表的渲染性能稍微差一些。

于是我们决定开发插件,却发现它的不同版本插件机制还不太相同。所以我们在很早的时候,内部就引入了一个 ECharts 的插件开发,同时我们自定了一套 Superset 控制面板,让我们非常多的支持工程师在不懂编程的情况下,也可以相对比较简单地去开发出自己想要的报表。

我们来看一下 Superset 早期接入的过程。我们实际上最初是要一个横向的柱状图,但我们在使用 ECharts 时候发现,通过简单的配置,实际上柱状图和线状图,还有堆叠特效都可以通过简单的配置来改变,所以我们就直接把 ECharts 的基本图表接入进去了。同时我们开发了定制面板,比如说通过下拉悬框进行一些配置,就可以改变 ECharts 的图形展现。

我们接入一两个月之后,中国区的服务器光使用 ECharts 柱状图就达到了四百多个,接入的反馈还是不错的。但是还是会有一些问题,实际上这也是很多 BI 工具都会面临的一些问题。

比如说一个报表可能会有多个 Chart,意味着它的资源开销、对后台数据库压力会非常大。另外我们开发新的一些图表接入 ECharts 或者其他的一些库会发现过于复杂,因为 Superset 0.2x 版本的插件机制还是比较复杂的,同时早期 Superset 的 Bug 也比较多,我们本身还有太多定制化需求,人力支持也有一些不足。所以在之后,从上层的角度来看我们做了这样一个模型:

我们把 Dashboard 分为三类,上面这类叫 lowcode dashboard,也就是不需要编程就可以实现的 Dashboard,开发周期大概是一到三天。中间叫 fastly built dashboard,让我们的支持工程师在只会 Python 这种语法友好的语言的情况下,就可以开发出自定义的图表。如果说这种还不能满足我们真正的需求,我们可能就要把它当成一个独立的 APP,用前后端分离的方式进行实现。

引入 Dash

我们做了定义之后发现我们的需求实际上是在中间层,我们需要从中有一些突破,所以我们后来在选型之后发现了这样一个工具,叫做 Dash。Dash 实际上就是一个用 Python 去开发动态化图表的工具,同时它提供了一个非常友好的接口,让我们只知道这些 ID 就可以完成事件的绑定。同时它作为一家商业公司还提供了一个企业版本,但我们主要用的还是它的开源版本,并且因为我们有自己的工程师,就会做一些改造。

使用 Dash 的好处就是它是一个纯 Python 开发框架,让我们的很多支持工程师可以相对快速的上手进行自定义报表创建。同时我们可以复用很多 Python 基础包提供的能力,这些包我们可以直接拿来用。另外我们发现图表中有很多不同数据展示的时候,因为我们是同一个数据源,这样用 Python 可以自定义数据源和不同 Dashboard 中间对应的 Chart,可以减轻对于数据库的压力。

在这个过程中,我们也把最新版本的 ECharts 引入了,获取了更多图表的整合,并且我们采取的措施没有对它进行过度的封装。我们就直接把 option 传入,只不过在 Python 中要使用的是符合标准的 Json 这样就可以。这样的话我们可以参考 ECharts 官方的惯例进行内部培训,让大家快速上手。

案例展示

以下是我们使用 Dash 以及 ECharts 能做的一些报表。首先是一个结合百度地图的报表。我们有很多物料从不同的地方运到工厂,它会记录这些距离。

从图表展现形式上我们可以看到,这样一个工具可以方便我们的支持工程师很快定位这些货车运货是否及时到达。我们可以看到货车实际上还分了几个不同的状态,绿色、黄色和红色,直观对应的是运货的延迟程度是否在我们能接受的范围内,同时导出功能也可以把数据按照我们想要的格式筛选下载下来。

上图是 A 股的交易量图表,方便我们简单的选股,后台用了一个叫 TuShare 的库去获取真实数据。

Dash 基础操作讲解

下面是一个用 Dash 和 ECharts 结合的 Gallery 教程,里面有一个完整例子。

以下是一个简单的安装操作:

下面这部分类似于一个 Workshop 的形式。我们会讲一下 Dash 和 ECharts 的基础,提供一两个例子,让大家快速上手。

Dash 的使用分为以下四个方面:数据获取、页面布局、图例使用和信号传递。我们把这四个方面都掌握了之后就可以很轻松的上手。

Dash 的一个好处是什么样的数据都可以获取。这里为了方便,我们使用一个随机数生成一周 7 天的数据。

其他的数据是怎么获取呢?你可以使用库里的方法获取数据,或者针对数据库、文件这样的数据用 Pandas。读取文件 CSV 或者 Excel 就更容易了。

除了数据获取,我们第二个关注点就是页面布局。Dash 的页面布局并不是那么简单,因为它是纯 Python 来写,我们通过 Dash 里面封装的 HTML 到 div 这样去创建一个 div 对象。

关于图例使用这部分,这里面我们使用了一个 ECharts,要注意的是它的 Option。Option 传入要设定它的 X 轴,比如说 X 轴一周 7 天;Y 轴是值类型的。类型都是在 series 里面,它是一个数组,可以接受多组信号的传递。

信号传递这部分,我觉得这是 Dash 的一个精髓。它抽象了几个原语,第一个是 output,第二个是 input,还有 state,分别对应它的输出输入以及状态。

比如说这里面的例子。我们的定时器用 ID: interval 来表示,它的 n_interval 就是第几次,每一次它的跳动都会进行一次触发。当它触发的时候会影响到 Output,也就是 ECharts option 的变化。然后我们在改变的时候,因为是一个 EChart 对 Option 的更新,我们要拿到 ECharts Option 当前的状态。比如说这里面我们可以看到 Option 对应的 opt 变量,它就是对里面的 series 第一个元素的 Data 进行调用。

这里面要注意的是 Input、State 可以为多个,实际上 Output 也可以为多个,但是大多数情况下都是写一个,因为你默认大多数的函数返回值都是一个的,也就是说 Output 要对应 return 后面的,而 Input 和 State 实际上是按照顺序依次是对应函数的参数。这是使用 Dash 完成它信号传递的方式。完整的代码在这里。

ECharts 基础操作讲解

我们现在相对深入去了解一下 ECharts Option。下面的例子中,我们实际上关注的是 X 轴为周一到周日,Y 轴是随机数。

X 轴为 category 类型的时候,我们要把 Data 直接放在这里面,传一些数值或者其他的一些数据。

Y 轴一般常规是数值形态,我们就设置一个 Type 为 Value,它的 Data 我们放在 series 里边。

这里边 Type 要特别注意,我们如果把它设置成一个 Line,它就是一个线状图;如果是设置成 Bar,它就是个柱状图。这是 ECharts 非常强大的一个地方,因为它通过简单的配置就可以在不同的图表之间快速切换。

比如说下面我们想要一个线状图。我们要求一个面积,设置不同的参数就可以得到这样一个图。而右图并不是一个线状和柱状的混合图,它是一个线状图,后面是一个 markArea。我们是专门用一个区域作为一个 mark,实际上就是把周三到周四这块标记为橙色。

下面是一个线状堆叠,还有一个线状堆叠的区域。因为这是两个图,数组就有两个。但我们看它的数值是一样的,它应该是重叠的,我们想把它堆叠起来,就是在里面设置一个 Stack。设置 Stack 之后,我们给它同样的一个名称,然后就可以堆叠在一起。这个时候我们如果再加上一个 areaStyle 这样一个参数,它就变成一个在区域覆盖的图。

接下来我们看一下柱状图。很多时候有一些图表,比如说生产线上某一个区域超过了一个阈值,我们要对它标红,平时给它标绿。在 series 传入数据的时候,除了传入数值形态,我们还可以传入进去一个 Dict,然后这块我们就可以对这一个单独数据调整样式。比如说这里面的传入 Value 是 200,设置大于 150 的时候会触发。右图是柱状堆叠,原理也是一样的。

我们看另外一个稍微复杂的例子。我们在使用 ECharts 的时候也非常看重这一个特性,也就是它能跟一些地图结合。这个例子来自 ECharts 官网,是全国主要城市的空气质量。从数据上来看,我们可以看到它里面有很多的蓝色小圆点,还有绿色大圆点,它是用不同的样式展现出来的。它们都是不同城市 PM2.5 的数据,只不过对于排名前十位的用绿色标注,而其他的都用蓝色。

用 Dash ECharts 要实现这样一个图,首先我们要有数据。数据分两类,第一类是这些城市的坐标,第二类是 PM2.5 的数值。然后我们定义一个函数,按照我们想要的 ECharts 数据进行转换。

这里面生成了两类数据,有一个是这些 points 本身,另外就是我们算出来的前十名城市的数据。我们在 ECharts Series 里面放两个数据就可以完成图表的展示。

除了常规的操作之外,我们需要引入百度地图的脚本,然后我们用 external_scripts 在 Dash APP 声明的时候传入它。然后我们的 Layout 这里面使用了另外一个 Dash ECharts 的特性,就是说我们在 Python 里面去声明一个 JS 的函数去调用,调整默认的那个圆。

ECharts 结合百度地图的 Option 配置就是这样,我们重点关注点是在 Bmap 这块。Bmap 要设置默认情况下的缩放尺寸、中心位置以及它的 mapStyle。对于 mapStyle,你可以传入一个大数组进行一个相对复杂的定制,也可以使用它默认的一些模板。

上面这里是我们数据 series 的配置,我们可以看左边是普通的 Points 点,右边是 Top10。Top10 里面加了一些特殊效果。

小结

以上就是我本次分享的所有内容,包括了我们在使用 ECharts 的一些经验的分享,以及两个简单实例的上手,谢谢。

相关推荐

崩溃!改了十遍还是错?4 组 Vue 技巧让你秒变大神

凌晨一点,办公室只剩键盘敲击声和空调的嗡鸣。盯着屏幕上反复报错的Vue项目,咖啡凉了又热,改完的Bug却像打地鼠一样冒出来——这是不是你无数个加班夜的缩影?别担心!今天分享4组超实用的...

Vue3基础难点总结

区别生命周期的变化整体来看,变化不大,只是名字大部分需要+on,功能上类似。使用上Vue3组合式API需要先引入;Vue2选项API则可直接调用,如下所示。//vue3<s...

无所不能,将 Vue 渲染到嵌入式液晶屏

该文章转载自公众号@前端时刻,https://mp.weixin.qq.com/s/WDHW36zhfNFVFVv4jO2vrA前言之前看了雪碧大佬的将React渲染到嵌入式液晶屏觉得很有意思,R...

Vue3 要起飞了!响应式性能超级大提升!

在Vue.jsNation2025上,尤大大公布了Vue3.6的更新内容:1、响应式性能的大幅度提升2、Vapor模式(实验性)3、内部类型的简化1、响应式性能的大幅度提升Vue3.6...

前端人必收!10 个 Vue3 隐藏技巧,解决 99% 开发卡顿?

写Vue3项目时,是不是总遇到数据更新慢、组件通信乱、打包体积大的问题?别慌!今天带来10个连老前端都直呼“真香”的实战技巧,从性能优化到代码复用,全是能直接抄进项目的硬核方案,看完开发效...

对于Vue3和Ts的心得和思考

1前言Vue3已经正式发布了一段时间了,各种生态已经成熟。最近使用taro+vue3重构冷链的小程序,经过了一段时间的开发和使用,有了一些自己的思考。总的来说,Vue3无论是在底层原理还是在实际开发...

vue3还用this吗?getCurrentInstance获取当前组件实例

在Vue2中,this关键字代表当前组件实例。在组件的选项对象中,this可以用于访问组件实例的属性、方法以及Vue实例的一些特定方法。在Vue3中,我们发现this是undefined...

Vue3快速入门

  1.核心语法  1.1选项式和组合式的区别  Vue2的API设计是Options(选项)风格的。  Vue3的API设计是Composition(组合)风格的。  Options类型的API...

Vue 3 进阶用法:异步组件

一、代码分割一个大型前端应用,如果所有代码都放在单一文件,体积会特别大,下载时间长,白屏时间久,用户体验差。代码分割(CodeSplitting)是一种有效的优化方式。提前把代码切分为多个小块,只下...

如何在 Vue3 中更好地使用 Typescript

TypeScript为Vue应用带来了强大的类型系统支持,Vue3更是从底层开始使用TypeScript编写。本文将介绍Vue3中自带的TypeScript类型工具及其最佳实践,通...

Vue3 页面卡顿严重?7 个实战技巧让渲染速度飙升 80%!

作为前端工程师,你是不是经常遇到这样的糟心事:明明用着最新的Vue3框架,页面却卡得像蜗牛,用户疯狂吐槽体验差,自己调试半天也找不出原因?别慌!今天就分享7个超级实用的Vue3性能优化实战...

最近很火的Vue Vine是如何实现一个文件中写多个组件

前言在今年的VueConf2024大会上,沈青川大佬(维护Vue/Vite中文文档)在会上介绍了他的新项目VueVine。VueVine提供了全新Vue组件书写方式,主要的卖点是可以在一个文...

vue3新手入门(9)vue3中的强大功能使用hooks示例

今天学习下vue3的自定义hooks,自定义Hooks是一种非常灵活的方式来组织和重用组件逻辑。它们本质上就是普通的JavaScript函数,可以在组件的setup()函数中被调用,并返回...

在vue3中动态加载远程组件

前言在一些特殊的场景中(比如低代码、类似于APP的热更新),我们需要从服务端动态加载.vue文件,然后将动态加载的远程vue组件渲染到我们的项目中。今天这篇文章我将带你学会,在vue3中如何去动态加载...

崩溃!组件数据总丢失?5 组 Vue2/3 对比技巧颠覆认知

凌晨两点,办公室只剩下键盘敲击声和咖啡机的嗡鸣。盯着屏幕上报错的Vue项目,反复检查代码却找不出问题——数据突然消失、组件莫名重新渲染,这些“玄学”问题是不是让你血压飙升?别慌!今天带来...