作者 | 流形
作者陈屹,花名流形,2010 年加入阿里,《深入 React 技术栈》作者,目前带领阿里巴巴数据技术与产品部体验技术团队。
在数字经济时代,数据的重要性堪比石油。大数据的四个特点:Volume(数据体量大)、Variety(数据类型繁多)、Velocity(处理速度快)、Value(商业价值高),只要合理利用数据并对其进行准确的分析,将会给企业带来很高的价值回报。
数据体验技术团队从一开始建立就致力于打造数据领域体验技术的标杆。经过多年的深耕,形成了一整套面向两个阶段的用户产品的体验技术架构。
在数据建设侧,完成大型 Web 应用架构,TypeScript 方案的 Iron-Redux,加 API 服务 Pont。上层特色的服务编排引擎和 SQL 编辑器的深挖,在工具层体验能力增色不少。在数据消费侧,我们致力于构建以 BI 为搭建数据报表等核心能力,上层特色的数据可视化,数据艺术和数据安全都在各领域有深度贡献。
下文会重点介绍 SQL 编辑器,BI 平台,数据可视化,数字艺术,数据安全领域。从数据领域的见解开始,讲下技术上的建设和未来发展路径。
SQL 编辑器
在数据采集,加工,管理,应用的链路中,编辑器都充当着开发者最重要的伙伴。在前端领域,编辑器是高复杂度的领域,而 SQL 编辑器在这个领域中又是垂直领域的建设。我们在设计编辑器的过程针对理解语法和理解语境这两个点作了深入分析和优化。
理解语法
回顾人学习一门新语言的过程,无外乎两种方式,要么翻阅百科字典,从 a 到 z,无论常用字还是生僻字,可以组成哪些词语,悉数记于脑中;要么与人交谈,记下其他人遣词造句的习惯,转为己用,与人交谈的次数越多,交谈的人群范围越广,积累下的话术也越为丰富,面对同一个问题,心中可供选择的答案也越多。
编辑器理解语法的过程亦是如此,基于产生式进行分析或是基于样本进行模型训练与识别。一门语言的产生式定义可以视为这门语言的百科字典,详尽的枚举出词法和语法的所有场景,清晰的描摹出边界。SQL 语言的语法相对简单,结构性较强就比较适合采用基于产生式分析的方案。而对于 Python,Shell 这类语法复杂,或灵活度高的语言,基于产生式分析提供的关键词提示,在实际应用中难以真正起到提高开发效率的目的,基于业务场景的历史数据进行模型训练,提供包含业务含义的代码片段的提示显得更有意义。
架构图
理解语法可以说是编辑器最为基础的能力,不同的编辑器方案均有不同程度的实现,在我们的方案设计与实现的过程中,最为关注的三个方面分别是可扩展,易维护,高性能三个方面。
可扩展性:编辑器的载体产品经常提出一些定制化的需求,譬如支持变量语法,注入全局变量,或者是调整提示内容优先级,新增一些快捷键操作。尽管最终效果的呈现都是在界面上,实际解决这些问题的原点却不尽相同。因此,对编辑器作了三层架构设计,产生式层,解析层,组件 UI 层,各层级间明确 API 规范来保证能力的解耦与扩展性。
易维护:在需求支持的过程中,我们无可避免的要对语言的产生式进行修改,在这个过程中任何思考上的疏忽都有可能引入二义性语法,或者左递归语法,导致解析异常,无法提示出正确的信息或是陷入死循环。于是,产生式调试是语法拓展的核心工作之一,我们需要追踪用户输入的解析过程,在哪一个子句处没有匹配到目标产生式,从而去检查相应的产生式定义是否存在问题。
高性能:高性能的保证和提示精度的调控,提示规则的设计是相辅相成的。总能找到一处语法定义是 LL(k) 识别不了,但是 LL(k+1) 可以识别的。性能的要求导致我们不能无限的提高回溯的步长,但是同时还要达到一定精度的要求。
由于 SQL 本身流程控制能力上的局限,在实际开发中往往需要借助 transform 或 udf 的方案,结合 Python,Shell 一起开发。未来,我们也会用机器学习的方案,来支持 Python,Shell 的语法提示能力。
理解语境
为了做到理解语境,在充分理解语法的基础上,还要进一步对语法所在的上下文进行分析,才能得出最终的结论。语法解析的过程实际上就是将用户输入转化为抽象语法树的过程,因此理解语境所需的上下文尽在树中。但是在为编辑器赋予理解语境能力的过程中,我们发现最大的挑战并不在于分析逻辑的实现本身,而是在于它的复制量产。由于业务上要求支持的方言众多,方言彼此间有着或多或少的语法差异,既要保持不同方言间语境理解能力的齐平,又要避免冒烟囱式开发。经过分析我们发现针对每一种语境理解的实现,关注点都集中在几个关键的终结符与非终结符定义上,围绕这些关键节点,建立一个有限状态机,新的方言接入时提供一个映射关系来说明关键节点之间的映射,语境理解能力就完成复制量产。这套机制的建立也意味着编辑器能力开放的议题中,语境理解能力的开放已经初具雏形。
理解语境的另一方面体现在与数据分析能力的结合。结合数据探查的能力,对于数据研发中一些常见的数据质量问题可以做到前置检测,在开发过程中予以提示并引导解决,从而改变传统数据治理方案流程滞后,导致计算资源浪费的问题。以数据倾斜治理为例,当用户任务执行失败,经过探查分析发现是由于数据倾斜所致,由于数据倾斜存在一个持续期,因此在持续期内,用户开发中再次操作引发倾斜的字段时,会将热值信息予以提示,引导用户进行改写。除去这个例子,其他类型的数据质量问题,诸如暴力扫描,join 两侧字段类型不一致,以及其他 map join 优化场景都可以通过开发时的检测与提示进行规避。
语法提示
别名识别
关键词修正
BI 平台
BI 平台是帮助我们更好地利用数据提高决策质量的中后台应用架构。它是从大量数据前端应用中沉淀出来的,上层支撑了 Quick BI,Quick A+ 等数据产品,汇集并沉淀了数据分析的核心能力。
Quick BI 是 BI 平台支持的核心,也是数据中台拳头级产品。2019 年,成为中国首个且惟一入选 Gartner BI 魔力象限的产品。BI 是一个典型的重交互场景,整个 BI 的分析链路包括数据引入、数据建模加工、报表搭建、交互分析、访问分享和集成。
BI 是非常有挑战的搭建场景,搭建能力对阿里数据中台来说,就像水和空气一样重要,搭建能力很大程度决定了数据中台竞争力。大量的产品需要搭建的方式来赋能业务人员,类似 Powerpoint 一样富客户端的交互方式;动辄百万条数据的加载对性能的挑战,单页面项目、ISV 开放生态对接等对工程化充满挑战。因此,我们抽象出渲染引擎内核 bi-designer 同时支持了两个 BI 的快速迭代。
目前,我们携 bi-designer 加入到阿里集团低代码引擎组织,成为核心架构组的一员,专注于数据领域搭建方向,正在积极的递交提案拓展阿里低代码引擎协议,并进行 bi-designer 规范化改造,与 AliLowCodeEngine 引擎进行代码融合。
bi-designer 数据搭建引擎有如下几个特色:
三合一布局
我们三种业务场景天然需要三套布局的能力:
- 数据搭建 - 流式布局。
- BI 报表 - 磁贴布局。
- 大屏 - *布局。
bi-designer 通过插件机制内置了这三种布局能力,使流式、磁贴、*布局间可无缝切换,在不同的产品透出不同布局能力。*布局采用 Keynote 高仿真方案,支持吸附、对齐、组合、锁定等功能;磁贴布局也做了高度自使用、宽高智能拖拽等体验优化。
数据模型驱动
BI 搭建拥有强大运行时分析能力,比如基于 OLAP 数据模型的同数据集自动关联功能,在图表内点击、框选操作触发其他组件查询并自动过滤筛选。
简单的联动配置背后需要一套运行时解析能力,bi-designer 提供了一套运行时事件机制 runtimeConfig
,将任意组件配置映射成复杂事件关联效果,比如点击控制图表属性变化、点击控制取数参数变化、点击控制筛选条件值的变化。在取数上也内置了数据模型处理,针对筛选条件多对多关联、联动、值同步,以及任意组件(如线图)具有展示与筛选双重功能的能力。
懒渲染
由于 BI 场景数据量动辄上百万条,我们在做了大量组件优化的同时(虚拟滚动、数据抽样等),bi-designer 渲染引擎也内置了组件按需渲染的能力。
对于数据取数场景,我们也做了特别优化,懒加载的组件不会阻塞取数,而只阻塞组件本身渲染,这样可以在组件出现的瞬间直接加载数据,而不是重新取数。
被集成能力
BI 报表在阿里内部和云上市场都有强烈被集成诉求,若干张报表或者设计器集成到已有系统逐渐成为一种趋势,我们开发了 bi-open-embed 并集成 bi-designer 能力,让渲染引擎可以被轻松集成到任意平台。我们对 Client、Server 端抽象了三层通用中间层 - PostMessageProxy、Router、EmbedAPI,分别定义了消息派发、指令接收以及指令执行,Server 端底层对接 bi-designer 引擎,Client 端对接接入方应用。
被集成领域中,组件安全隔离我们也下了功夫,从组件打包阶段开始,就利用构建工具进行样式隔离,组件脚本加载时进行 JS 环境变量隔离。在集成 API 上我们也从权限体系开始设计,到报表区块、筛选、主题等模块的控制,还可支持动态传入取数参数影响报表取数结果等等。
低代码
低代码能力也是我们数据搭建平台今年重点建设方向之一。低代码包括 NoCode 与 LowCode,NoCode 就是基于模型或者标准化模版,不需要写代码即可支持通用场景搭建,LowCode 则是在 NoCode 的基础上,辅助少量业务逻辑代码,比如变量绑定或者或者动作,实现更多定制业务逻辑的覆盖,其适用范围更广。
集团中后台搭建采用 LCDL(Low-Code Definition Language)描述低代码业务协议,主要包括应用低代码定义语言、页面低代码定义语言、组件低代码定义语言。围绕这三个核心协议,拓展出四个可插拔的核心模块:
- 入料模块:让渲染引擎可接入任何物料,并识别物料特征,自动完成对接。
- 编排模块:设计器核心功能,包括组件编排、逻辑编排、事件编排等,是搭建的核心。
- 渲染模块:搭建产物需要被分发到不同端,甚至小程序,从安全性到兼容性都是渲染模块要解决的问题。
- 出码模块:所有低代码搭建产物都可出码,使产物可二次开发,FY21 还会持续探索 Pro-Code 与 Low-Code 完全互转。
数据搭建场景较为垂直化,且可依赖数据模型驱动,所以很久以来都没有强烈低代码诉求。但随着数据中台业务越做越大,盒马、菜鸟、本地生活、饿了么等等经济体 BU 数据团队的加入,具有低代码能力的数据产品搭建诉求越来越强烈,所以我们今年加入了集团低代码引擎组织核心团队共建,向组织输出数据场景搭建能力,从组织获取低代码引擎能力。
数据可视化
人类在处理信息的能力,视觉远超其它五感处理能力,在《Information is Beautiful》一书中,作者将视觉类比成计算机网络的带宽,达到 1250MB/s,触觉排在第二类比成 USB 接口,有 125MB/s,听觉和嗅觉类比成硬盘只有 12.5MB/s,而味觉就忽略不计了。数据可视化,就是在我们清洗关键数据之后,将数据呈现给用户,就像一道菜品精美的摆放,给你带来更多想象。
可视化一直是数据分析重点一环,工业界和学术界在可视化的研究也有高度重合的部分,脱离了分析的可视化是缺少灵魂的。上图来自于一家调研公司,可以看到数据分析有一个发展阶段,描述分析,解释分析,探索分析,预测分析,规范分析。规范分析是数据分析的最终阶段,它已经可以解决我们怎么做的问题,类同于人工智能的终极阶段。
而可视化在之前的几个阶段都有一一匹配的能力,这也是可视化与大部分认知不同的地方,可视化远远不只是解决数据如何展示的问题,更重要的是如何传递信息,甚至解决的是如何传递更多的有效信息。
基础架构
我们团队在这四个阶段都有布局,在可视化图表上,也是我们立身之本。我们在 BI 工具发展上构建了整体数据团队可视化能力,基于 D3,G2 构建了完善的基础层。结合业务能力在工具层,拥有完善的交互式分析能力。通过上层图形语法和数据模型标准的映射,我们得以用一套架构来实现可视化内核,在内核层大量增强了基础库的能力。
BI 场景有极其丰富的可视化场景,目前 Quick BI 支持 40+ 种图表,包括用户最常用的折线图、柱状图、堆积面积图、条形图、饼图和桑基图、排行榜、指标卡趋势图这些业务场景化图表。
如何让这些图表更快速的开发和扩展一直是我们要解决的问题。因此,我们抽象出了 charts-bi 图表公共层,它包括统一的数据处理层、图表默认配置管理、图表极限情况处理、子图表、子组件包括图例和 Tooltip 等原生的渲染。尽管,我们图表渲染底层基于 G2,但可以说我们的 BI 场景图表是 G2 在集团应用最丰富的场景之一,同时我们也深度参与了可视化基建的共建。
经过一年多的努力,2019 Quick BI 在 Gartner 象限报告中在数据可视化上在满分 5 分的情况下达到了 4.7 高分,超越微软 PowerBI,仅次于以可视化著称的 Tableau。报告称 Quick BI 在数据可视化功能方面被评为杰出。它支持丰富的图表类型和类似 Excel 的报告。它还为参数化数据获取和基于表单的回写提供了专用功能。
智能可视化
智能可视化是一个跨界领域,诸如自动洞察,可视化设计,可视化配置推荐都是智能可视化的方向。Gartner 预测,未来数据分析是增强分析时代。普通用户发现数据洞察的成本很高,用户需要尝试找到有规律的一些指标,通过可视化的方式来验证甚至是发现规律,这种反复试错的成本非常高。因此,自动洞察可以说是对用户在基本业务洞察之外的补充。
自动洞察能够在用户提供的数据集上,自动进行特征的分析,数据清洗,根据梳理的 insight 类型进行自动的匹配,找到隐藏在数据集中的知识,提供给用户。这条链路的不断优化,最终手工分析的时代也会被自动洞察所替代,只有一个按键就可以让用户找到最有效的信息。
近几年,产学研一体趋势显著,微软的 Power BI 在这个领域颇有建树,推出了 Quick Insight 就是与 MSRA 合作,是自动洞察方向的开荒者之一。今年,团队在对内侧的 BI 工具上已经落地了自动洞察功能,提供给小二更智能的数据决策工具而为之努力。
在未来布局上,数据世界真实的描绘不应该是静态的,它是真实在变化的,我们在变化中需要呈现一个变化的规律,这是现代数据分析上比较缺失的。未来,在数据故事和自动洞察上发力。将数据可视化能力从静态交互分析,发展到动态交互分析上。进一步,挖掘数据中更多有效信息,辅助人作决策。
数字艺术
如果说 BI 和数据可视化是帮你从数据中发现信息的工具,数字艺术则是展示和传播你的数据故事的媒介。无论是一个大屏,还是一个可交互装置、Web 页面、富媒体,作为数据可视化的延伸,我们始终在探索更新颖的形式,更前瞻的技术,来让你的故事拥有怦然心动的力量,在从纷繁的信息中脱颖而出,无须多言,便能打动听众。
团队与 UED 紧密合作,负责了集团多年的双十一和九号馆的大屏和互动展区设计开发,支持了集团 PR、GR 部门众多的高级接待和对外访问活动,同时以技术支持和平台支持的形式,协助集团各个BU团队开发数据可视化、BI、大屏、展示型内容和传播内容。
在这个过程中,积累了一套从数据处理算法、到渲染引擎、可视化框架,以及搭建平台的解决方案。
异构渲染
为了满足不同场景和内容的展示需求,充分发挥不同渲染平台的优势,我们在渲染框架中原生支持了跨平台渲染。
通过一套统一的数据源/数据算法,统一的地理空间规范,和统一的相机状态定义,来保证不同渲染架构输出的渲染结果空间对齐,然后通过实时推流和 WebView 对不同渲染架构的内容进行融合,实现多种平台渲染内容的合并输出。
通过异构渲染,我们得以在一个场景中,融合来自 Polaris 的实时数据可视化能力、UE4 的细节制作和渲染能力、G2 丰富的可视化图表、高德庞大的地图数据,各取所长,融合为一个可交互的实时渲染内容。
Web3D 渲染引擎
无论技术流行趋势如何变化,Web 平台依然承载着我们和核心技术和产品形式。我们始终相信,Web 平台有着未被发掘的强大表现力。受限于设备性能和兼容性的妥协,大家已经习惯将 3D on Web 视为一种能用即可的“降级方案”,然而 Web 技术的应用领域已经发生了巨大的变化,基础设施和硬件设备也不断的更新换代,现代 Web3D 渲染引擎,不应该总向十年前的游戏引擎看齐。
我们的渲染技术始终以 three.js 为根基,作为标杆级的 WebGL 引擎,three 无可匹及的强大社区支持着我们的快速发展,当我们试图摆脱 webgl 的限制时,选择保留了 three 所有的上层设计和场景定义,兼容多数 three 接口和社区插件的情况下,重写渲染层,实现了(当时)功能最完整的 WebGL2 引擎,显著提升性能效果,实现在浏览器中实时渲染上亿顶点的大型场景。同时引入了高效的 GPGPU,来实现更加复杂的粒子动画。
从 WebGL2 到未成行的 WebGPU ,限制 Web 3D 渲染能力的已经不再是图形 API,而是渲染流水线和图形算法,渲染管线不升级,图形 API 再怎么升级也不会带来质的变化。
在 2019 年,我们作出了一个大胆的尝试,直接将桌面游戏引擎的高清渲染管线,实现在 WebGL2 之上,并在双十一项目中使用。
参照成熟游戏引擎的渲染管线设计,我们使用多种渲染路径来渲染场景的不同成分,对不能完整支持 Deferred Shading 的材质,或者需要兼容的现有入库组件,使用前置渲染或者不完整的延迟渲染,其中基础场景使用完整的Deferred Shading 管线。Deferred Shading 管线中,除了获得在 shading 阶段强大的性能控制,完整的 GBuffer 更是解锁了众多屏幕空间算法,让我们可以高效的进行 SSAO 和 SSR 等复杂计算,甚至能在笔记本上流畅运行。
高清渲染管线为 Web 端的渲染能力迈上了一个新的平台,使得众多新技术的引入成为可能,我们能从学术、游戏、影视领域的最新成果中汲取养分,而不用再受限于实时渲染技术发展初期的古老算法。这也将是唯一一个有能力发挥 未来 WebGPU 潜力的渲染管线。
3D 地理系统
3D 数据可视化的场景虽然复杂而零散,但是多数和地理数据强相关,为了提高开发效率和服用能力,我们在 three 的通用场景定义之上,设计了一个轻量级的地理信息系统 — Polaris。将视觉效果的开发和业务逻辑的开发,全部简化为 Layer 开发,符合 schema 的 Layer 可以*叠加、组合、继承,然后交由 Polaris 渲染器渲染。同时积累了一套上百种 3D 组件的 Layer 组建库。
在 Polaris 中,我们按照真实比例和地理位置构建世界,可以向 Google Earth 一样,在一个三维场景中绘制从星系到地球、国家、一直到某个城市的某个楼宇内部,通过一个长镜头,将所有的场景贯穿起来,形成一个连贯的数据故事,而非 PPT 一般的分离图表。
算法服务
一个 3D 空间的构建,是对大量原始地理数据的层层处理,处理的过程往往从高德的原始地理数据开始,经过过滤、简化、拔高,变为3维模型,然后通过算法进行细化、匹配,生成建筑细节,然后根据 DEM 生成地形和山脉,对于特写区域,需要通过人工制作高精模型,再通过算法对齐地理空间,如果是城市景观,还可以通过算法生成车水马龙、广告牌、霓虹灯等装饰内容。
所有这些过程都涉及到庞大的数据输入和复杂的计算逻辑,我们已经在不同业务场景中生成过 30 多个城市和所有省份的场景数据,并且数据源和场景构建的需求在不停的更新着,手工管理将是一笔巨大的负担。因此我们构建了一个地理数据算法服务,来为 UE4 和 Web 端渲染平台提供等效的服务。
数据安全
数据产品中有表现力丰富的数据可视化能力、有高效的数据解读能力,但背后也隐藏着各种各样的数据安全风险,这些数据可能涉及到交易数据,也可能是行业趋势数据,这些数据如果发生泄漏被不法分子利用极有可能对集团和客户造成严重的损失,所以数据产品的各个生产环节都需要具备安全防御方案。
对于整个数据安全体系,从数据生产到数据查询的链路需要做数据脱敏和差分隐私,前端是数据产品向用户展示和交互的最后一环,也是整个生产链路中数据安全保障的最后一环。我们也需要配合全链路的数据安全建设,做到事前,事中和事后的保障。
数字水印
数字水印是在事前环节,起到警示、震慑的作用,提醒产品的访问者产品中展现的数据属于秘密信息,不可传播;以及在事后环境,帮助案件追查,当访问者对页面进行截图和传播后,可以准确的定位到案件的当事人,协助案件侦破。传统的网页水印方案是在端上直接绘制水印信息覆盖在文档流上或作为背景图片,但只要是具备一点前端知识的人都可以通过浏览器的调试器对水印信息进行删除甚至是篡改,所以我们要确保水印的真实性和水印的稳固性。
水印生产主要分两类。明文水印,它是指将可读的信息(用户姓名或其他警示信息)生成水印图片,主要目的是起到警示作用;加密水印,我们团队和安全专家一同共建的,将水印信息加密为不同形式的图片方案,比较有代表性的是结合了文件数字水印的理论:点阵水印、隐秘水印、浮雕水印,此类水印的特点是信息无法被篡改,主要用于案件追踪。
水印在生产环节进行了加密,由于无法解密,解决了水印的篡改问题。在水印部署过程中需要克服水印被删除的问题,我们针对常见的水印删除手段进行防御:
- 网络干预,阻止页面获取水印资源(图片和 SDK),对图片二进制流和sdk资源下发均采用与业务代码进行混淆,确保水印部署和业务逻辑执行过程交叉执行,无法单独中断
- 环境及 DOM 干预,通过修改和删除 DOM,对浏览器的 DOM 和关键原生 API进行劫持验证,确保 DOM 的修改可被监听和复原,无法复原的情况将中断业务逻辑
- 融合部署:对于重要的数据信息,通过 canvas 或图片方式渲染替代原有的DOM渲染,此时数据信息和水印信息融合为一个原子节点,无法单独删除
- 信息差手段:每个数据产品的页面均混合部署多套水印方案,通过虚实结合(可见水印、不可见水印)的方式确保不法分子无法完全删除掉页面中的水印
除了以上攻防手段,我们还在进行一些新型水印生产及部署方向的研究,目的是从更本质的方面对水印进行加固同时降低水印对产品的视觉侵入,目前具备可行性的是边缘水印(将水印的生产和部署在客户端进行,强化水印和页面内容的融合)和血缘水印。
数据监控
监控在数据产品中不仅是生产安全的重要部分,同时也是数据安全的重要保障,通常的监控主要关注 JS 报错和 API 接口报错,但数据产品需要对数据逻辑进行监控,例如用户正在分析自己商业数据,突然实时数据显示利润剧烈下跌,这很容易造成用户的恐慌。
我们在完成了监控平台 Clue 的基础建设上同时也在做很多数据场景的垂直建设:
- 非法环境识别。因为有数据透出,总是有黑灰产不断生长。他们通过第三方插件爬取数据接口,对数据进行非法汇总和反推,这时就需要对用户使用产品的浏览器环境进行检查,为打击黑产提供法律依据。针对这种场景我们会对部分原生 API 进行数字指纹加持,通过特征匹配,定位非法插件。
- 诊断报警。监控平台中报警的及时性和准确性是重中之重。对于数据展现来说,某些数据趋势跌 0 对于大客户和来说一定是出现了问题,但对一些小众客户或行业来说,部分指标的跌 0 可能是正常表现。因此,我们需要抽取指标信息、行业信息、大促信息等在内的多种特征对报警模型优化,通过报警信息的反馈机制不断的对报警模型持续优化,通过模型预测的方式对报警阈值进行动态调整,促使报警逐渐趋于准确。
写在最后
未来,数据与智能占据了风口。依靠着云上计算能力,提供强大的渲染与数据分析能力。在流程研发,分析洞察,科学决策等方面都是体验技术发挥至关重要力量之处。
倚靠业界和学界前沿方向探索,数据体验技术围绕数据应用的全生命周期进行建设和打造,数据的未来是星辰大海,望有志之士一同前来创造未来!期待与你一起用创意与代码为世界做出些许改变。欢迎交流:arcthur.cheny@alibaba-inc.com。
关注「Alibaba F2E」
把握阿里巴巴前端新动向