公开的实现方式总体上涉及数据可视化,且更具体地说涉及使用数据集的对象模型来进行数据集的交互式视觉分析。背景数据可视化应用使用户能够在视觉上理解数据集,包括分布、趋势、异常值、和对做出业务决策重要的其他因素。一些数据元素必须是基于来自选定数据集的数据来计算出的。例如,数据可视化经常使用总和来聚合数据。一些数据可视化应用使用户能够指定可用于聚合计算的“细节级别”(lod)。然而,为数据可视化指定单个细节级别是不足以建立某些计算的。一些数据可视化应用提供用户界面,其使用户能够通过选择数据字段并将它们放置在特定的用户界面区域内以间接地定义数据可视化来从数据源建立可视化。见例如2003年6月2日提交的标题为“computersystemsandmethodsforthequeryandvisualizationofmultidimensionaldatabases”的序列号为10/453,834的美国专利申请(现在为第7,089,266号美国专利),其通过引用被全部并入本文。然而,当存在复杂的数据源和/或多个数据源时,可能不清楚基于用户的选择生成什么类型的数据可视化(如果有的话)。此外,一些系统构建的查询产生的数据可视化并不是用户所期望的。在一些情况下,一些数据行被省略(例如,当事实表(facttable)之一中没有相对应的数据时)。在某些情况下,数字聚合字段产生夸大的总计,因为同一数据值会被多次计数。这些问题可能特别成问题,因为最终用户可能意识不到该问题和/或不知道是什么导致了该问题。概述组合来自多个表的数据的生成数据可视化可能是有挑战性的,尤其是当有多个事实表时。在一些情况下,在生成数据可视化之前构建数据的对象模型可能是有益的。在一些实例中,一个人是关于数据的特定专家,且这个人创建对象模型。通过将关系存储在对象模型中,即使用户不是专家,数据可视化应用也可以运用该信息来帮助所有访问数据的用户。对象是所命名的属性的集合。对象常常对应于真实世界对象、事件、或概念,例如商店。属性是对象的描述,其在概念上与对象成1:1关系。因此,商店对象可以有与它相关联的单个[经理姓名]或[雇员计数]。在物理级别上,对象常常被存储为在关系表中的行或者被存储为json中的对象。类是共享相同属性的对象的集合。比较在一个类中的对象并对它们进行聚合必须是在分析上有意义的。在物理级别上,类常常被存储为关系表或者被存储为json中的对象的阵列。对象模型是类的集合和在它们之间的多对一关系的集合。通过1对1关系相关的类在概念上被视为单个类,即使它们对用户意义上是不同的。此外,通过1对1关系相关的类可以在数据可视化用户界面中呈现为不同的类。通过添加捕获关系的关联表,多对多关系在概念上被分成两个多对一关系。一旦类模型被构建,数据可视化应用就可以以各种方式帮助用户。在一些实现方式中,基于已经被选择并放置在用户界面中的工具架(shelf)上的数据字段,数据可视化应用可以推荐附加字段或者限制什么动作可以被采取来防止不可用的组合。在一些实现方式中,数据可视化应用允许用户在选择字段方面的相当大的自由度,并且使用对象模型以根据用户选择的内容来建立一个或更多个数据可视化。根据一些实现方式,一种生成数据可视化的方法。该方法在具有一个或更多个处理器和存储器的计算机处被执行。存储器存储被配置为由一个或更多个处理器执行的一个或更多个程序。该计算机接收指定数据源、多个视觉变量和来自数据源的多个数据字段的视觉规范(visualspecification)。视觉变量中的每一个视觉变量与数据字段中的相应的一个或更多个数据字段相关联,并且数据字段中的每一个数据字段被标识为维度或度量。根据数据源的对象模型,计算机识别包括所有维度数据字段的最小子树,并从最小子树构建访问维度数据字段的查询。计算机针对数据源执行查询以检索元组的集合。每个元组包括维度数据字段的数据值的唯一有序组合。对于每个元组,计算机通过附加对应于度量数据字段中的每一个度量数据字段的聚合数据值来形成扩展元组。计算机然后根据扩展元组中的数据字段以及根据与数据字段中的每个数据字段相关联的视觉变量来构建并显示数据可视化。在一些实现方式中,视觉规范包括一个或更多个附加视觉变量,该一个或更多个附加视觉变量不与来自数据源的任何数据字段相关联。在一些实现方式中,度量数据字段的聚合数据值是根据维度数据字段聚合的。在一些实现方式中,计算机在计算机的图形用户界面中显示数据可视化。在一些实现方式中,显示数据可视化包括生成多个视觉标记,其中每个标记对应于相应的扩展元组。在一些实现方式中,图形用户界面包括数据可视化区域,并且计算机在数据可视化区域中显示数据可视化。在一些实现方式中,视觉变量中的每个视觉变量是以下项中的一项:行属性、列属性、过滤器(filter)属性、颜色编码、大小编码、形状编码、和标签编码。在一些实现方式中,使用聚合函数来计算聚合数据值,该聚合函数是以下项中的一项:sum、count、countd、min、max、avg、median、attr、percentile、stdev、stdevp.var和varp。在一些实现方式中,多个数据字段来自数据源中的多个不同的表。在一些实现方式中,数据源的对象模型具有多个对象,并且多个数据字段属于多个对象中的两个或更多个不同的对象。在一些实现方式中,视觉规范指定多个数据源,视觉规范指定来自多个数据源中的每一个数据源的一个或更多个数据字段,以及对象模型是多个数据源的对象模型。根据一些实现方式,生成数据可视化的方法在具有一个或更多个处理器和存储器的计算机处被执行。存储器存储被配置为由一个或更多个处理器执行的一个或更多个程序。该计算机接收指定数据源、多个视觉变量和来自数据源的多个数据字段的视觉规范。视觉变量中的每个视觉变量与数据字段中的相应的一个或更多个数据字段相关联,并且数据字段中的每个数据字段被标识为维度或度量。计算机针对数据源执行第一查询以形成维度元组,该维度元组包括维度数据字段d的数据值的不同有序组合。对于度量数据字段中的每个度量数据字段,计算机:(i)形成由维度数据字段d和来自包含相应度量的数据源中的表的主键(primarykey)的维度组成的维度集合s;(ii)针对数据源执行相应的查询,以检索包括s中的数据字段和相应度量的中间元组,而不进行聚合;以及(iii)根据维度数据字段d聚合中间元组,以计算相应度量的聚合值。对于每个维度元组,计算机通过附加对应于度量数据字段中的每个度量数据字段的聚合数据值来形成扩展元组。计算机然后根据扩展元组中的数据字段以及根据与数据字段中的每个数据字段相关联的视觉变量来构建并显示数据可视化。在一些实现方式中,视觉规范还包括一个或更多个附加视觉变量,所述一个或更多个附加视觉变量与来自数据源的任何数据字段不相关联。在一些实现方式中,计算机在计算机的图形用户界面中显示数据可视化。在一些实现方式中,显示数据可视化包括生成多个视觉标记,其中每个标记对应于相应的扩展元组。在一些实现方式中,图形用户界面包括数据可视化区域,并且计算机在数据可视化区域中显示数据可视化。在一些实现方式中,视觉变量中的每个视觉变量是以下项中的一项:行属性、列属性、过滤器属性、颜色编码、大小编码、形状编码、和标签编码。在一些实现方式中,使用聚合函数来计算聚合数据值,该聚合函数是以下项中的一项:sum、count、countd、min、max、avg、median、attr、percentile、stdev、stdevp.var和varp。在一些实现方式中,多个数据字段来自数据源中的多个不同的表。在一些实现方式中,数据源的对象模型具有多个对象,并且多个数据字段属于多个对象中的两个或更多个不同对象。在一些实现方式中,视觉规范指定多个数据源,视觉规范指定来自多个数据源中的每一个数据源的一个或更多个数据字段,并且对象模型是多个数据源的对象模型。根据一些实现方式,一种过程生成数据可视化。该过程在具有一个或更多个处理器和存储器的计算机处被执行,该存储器存储被配置为由一个或更多个处理器执行的一个或更多个程序。该过程接收指定一个或更多个数据源、多个视觉变量、和来自一个或更多个数据源的多个数据字段的视觉规范。每个视觉变量与一个或更多个数据字段相关联,并且每个数据字段被识别为维度d或度量m。在一些实现方式中,视觉规范是基于在用户界面中的用户选择来填充的数据结构。例如,用户可以将字段从数据字段的调色板拖到行工具架、列工具架、或编码工具架(例如,颜色或大小编码)。每个工具架对应于在视觉规范中的一个视觉变量,且在工具架上的数据字段被存储为视觉规范的一部分。在一些实例中,有两个或更多个数据字段与同一个工具架相关联,因此相对应的视觉变量具有两个或更多个相关数据字段。当有两个或更多个数据字段与一个视觉变量相关联时,通常有指定的顺序。在一些实例中,同一数据字段与两个或更多个不同的视觉变量相关联。通常,单独数据可视化不使用所有可用的视觉变量。也就是说,视觉规范通常包括一个或更多个附加的视觉变量,该一个或更多个附加的视觉变量不与来自一个或更多个数据源的任何数据字段相关联。在一些实现方式中,每个视觉变量是以下中的一者:行属性、列属性、过滤器属性、颜色编码、大小编码、形状编码、或标签编码。在许多情况下,度量是数字字段,且维度是具有字符串数据类型的数据字段。更重要地,标签“度量”和“维度”指示数据字段如何被使用。对于数据字段的每个度量m,该过程识别相应可达维度集合r(m),所述相应可达维度集合r(m)由数据字段的根据在关于一个或更多个数据源的预定义对象模型中的多对一关系的序列从相应的度量m可达的所有维度d组成。注意,序列可以具有长度零,表示维度d和度量m在同一个类中的情况。在一些实现方式中,当维度d和度量m在预定义对象模型中的同一类中时,或者,度量m是在预定义对象模型中的第一类c1的属性,维度d是在对象模型中的第n类cn的属性,且n≥2,并且在预定义对象模型中存在零个或更多个中间类c2,…,cn-1的序列,使得对于每个i=1,2,…,n-1,在类ci和ci 1之间存在多对一关系时,维度d是从度量m可达的。注意,还有微不足道的情况,其中因为没有与视觉变量相关的维度,或有不能达到任何维度的一些度量。这是有效的可达维度集合。建立可达维度集合导致度量的划分。特别地,由当且仅当r(m1)=r(m2)时m1~m2定义的关系是等价关系。在大多数情况下,只有一个划分(即,r(m)对于所有度量是相同的),但在一些实例中,有一个以上的划分。对于每个不同的可达维度集合r,该过程形成相应数据字段集合s。集合s由r中的每个维度和数据字段中的满足r(m)=r的每个度量m组成。通常,每个数据字段集合包括至少一个度量。在一些实现方式中,没有度量的任何数据字段集合被忽略。在一些实现方式中,当没有度量的数据字段集合s被识别出时,数据可视化应用引起错误。在一些实现方式中,数据可视化应用(除了为包括一个或更多个度量的每个数据字段集合s创建的数据可视化之外)为没有度量的每个数据字段集合s建立附加的数据可视化。对于每个数据字段集合s和对于在相应数据字段集合s中的每个度量m,该过程将度量m的值上卷到由在相应数据字段集合s中的相应维度所指定的细节级别。然后,该过程根据在相应数据字段集合s中的数据字段和根据在s中的每个数据字段所相关联的相应视觉变量来建立相应的数据可视化。在一些实现方式中,建立相应的数据可视化包括使用根据视觉规范生成的一个或更多个数据库查询来从一个或更多个数据源中检索数据的元组。例如,对于sql数据源,该过程建立sql查询,并将该查询发送到适当的sql数据库引擎。在一些实例中,元组包括根据在相应数据字段集合s中的相应维度聚合的数据。也就是说,聚合是通过数据源执行的。通常,所生成的数据可视化被显示在计算机上的图形用户界面(例如,用于数据可视化应用的用户界面)中。在一些实现方式中,显示数据可视化包括生成多个视觉标记,其中每个标记对应于从一个或更多个数据源中检索的相应元组。在一些实现方式中,图形用户界面包括数据可视化区域,并且该过程在数据可视化区域中显示数据可视化。在一些实现方式中,将度量m的值上卷到由在相应数据字段集合s中的相应维度指定的细节级别包括根据在相应数据字段集合s中的相应维度来将包含度量m的数据表的行划分成组,以及为每个组计算单个聚合值。在一些实现方式中,使用以下聚合函数中的一个来计算单个聚合值:sum、count、countd(不同元素的计数)、min、max、avg(中数平均)、median、stdev(标准偏差)、var(方差)、percentile(例如,四分位数)、attr、stdevp、和varp。在一些实现方式中,attr()聚合运算符在其对所有行具有单个值时返回表达式的值,以及否则返回星号。在一些实现方式中,stdevp和varp聚合运算符基于有偏总体或整个总体来返回值。一些实现方式包括更多个聚合运算符或与在这里列出的聚合运算符不同的聚合运算符。一些实现方式使用聚合运算符的替代名称。在一些实现方式中,数据字段基于它们如何被使用而被分类为“维度”或“度量”。维度划分数据集合,而度量聚合在每个划分中的数据。从sql思维倾向来看,维度是在groupby子句中的元素,且度量是在select子句中的元素。通常,离散分类数据(例如,包含州、区域、或产品名称的字段)用于划分,而连续数字数据(例如,利润或销售额)用于聚合(例如,计算总和)。但是,所有类型的数据字段可以用作维度或度量。例如,包含产品名称的离散分类字段可以通过应用聚合函数countd(非重复计数)来用作度量。另一方面,表示人的身高的数字数据可以用作维度,按照身高或身高范围来划分人。一些聚合函数(例如sum)可以只应用于数字数据。在一些实现方式中,应用基于字段的原始数据类型来向每个字段分配默认角色(维度或度量),但允许用户超驰该角色。例如,一些应用将“维度”的默认角色分配到分类(字符串)数据字段,并将“度量”的默认角色分配到数值字段。在一些实现方式中,日期字段默认地用作维度,因为它们通常用于将数据划分为日期范围。维度或度量的分类也适用于所计算的表达式。例如,诸如year([购买日期]的表达式通常用作维度,将基础数据划分为年。作为另一个示例,考虑包括产品代码字段(作为字符串)的数据源。如果产品代码的前三个字符对产品类型编码,那么表达式left([产品代码],3)可以用作纬度以将数据划分为产品类型。一些实现方式使用户能够使用交互式图形用户界面来指定多个细节级别。一些示例使用两个细节级别,但是实现方式通常允许无限数量的细节级别。在一些实例中,根据在一个细节级别处的聚合计算的数据在第二细节级别处的第二聚合中被使用。在一些实现方式中,数据可视化包括被默认地用于计算聚合的“可视化细节级别”。这是在最终数据可视化中可见的细节级别。实现方式还提供了细节级别表达式,其允许用户在特定的上下文中指定特定的细节级别。一些实现方式规定确定期望数据可视化的特征的工具架区域。例如,一些实现方式包括行工具架区域和列工具架区域。用户将字段名称放置到这些工具架区域内(例如,通过从模式区域拖动字段),以及字段名称定义数据可视化特征。例如,用户可以选择纵条图,字段的每个不同值的列放置在列工具架区域中。每个条的高度由放置在行工具架区域内的另一个字段定义。根据一些实现方式,在计算机处执行生成和显示数据可视化的方法。计算机具有显示器、一个或更多个处理器、和存储器,该存储器储存被配置为由一个或更多个处理器执行的一个或更多个程序。该过程在显示器上显示图形用户界面。图形用户界面包括模式信息区域,其包括来自数据库的多个字段。该过程在图形用户界面中接收用户输入以指定第一聚合。第一聚合的规范通过多个字段中的一个或更多个字段的第一集合对数据分组,并且识别通过第一聚合创建的第一聚合输出字段。该过程还在图形用户界面中接收用户输入以指定第二聚合。在一些实例中,第二聚合的规范参考第一聚合。第二聚合通过一个或更多个字段的第二集合对数据分组。字段的第二集合选自多个字段和第一聚合输出字段。字段的第二集合不同于字段的第一集合。该过程基于第一聚合的规范和第二聚合的规范来建立视觉规范。在一些实现方式中,该过程包括使用从视觉规范生成的一个或更多个数据库查询来从数据库中检索数据的元组。在一些实现方式中,元组包括基于第二聚合计算的数据。在一些实现方式中,该过程包括显示对应于视觉规范的数据可视化,其中数据可视化包括基于第二聚合计算的数据。在一些实现方式中,所显示的数据可视化包括多个视觉标记,每个标记对应于从数据库检索的相应元组。在一些实现方式中,图形用户界面包括数据可视化区域,并且该过程在数据可视化区域中显示数据可视化。在一些实现方式中,图形用户界面包括列工具架(columnsshelf)和行工具架(rowsshelf)。在一些实现方式中,该过程检测将多个字段中的一个或更多个第一字段与列工具架相关联以及将多个字段中的一个或更多个第二字段与行工具架相关联的用户动作。该过程然后根据用户动作在数据可视化区域中生成视觉表。视觉表包括一个或更多个窗格,其中每个窗格具有基于与列工具架相关联的一个或更多个第一字段的数据而定义的x轴,并且每个窗格具有基于与行工具架相关联的一个或更多个第二字段的数据而定义的y轴。在一些实现方式中,该过程接收用户输入以将第二聚合与列工具架或行工具架相关联。在一些实现方式中,该过程根据与行工具架和列工具架相关联的字段从数据库中检索元组,并将检索到的元组显示为在视觉表中的视觉标记。在一些实现方式中,第一聚合和第二聚合的每个运算符是以下中的一者:sum、count、countd、min、max、avg、median、attr、percentile、stdev、stdevp、var、或varp。在一些实例中,第一聚合输出字段用作维度,并被包括在第二集合中。在一些实现方式中,第一聚合输出字段用作度量,并且第二聚合将聚合运算符之一应用于第一聚合输出字段。例如,在一些实例中,第二聚合计算第一聚合输出字段的值的平均数。在一些实现方式中,该过程在计算机显示器上显示图形用户界面。图形用户界面包括模式信息区域和数据可视化区域。模式信息区域包括多个字段名称,其中每个字段名称与来自指定数据库的数据字段相关联。数据可视化区域包括确定数据可视化的特征的多个工具架区域。每个工具架区域被配置成从模式信息区域接收一个或更多个字段名称的用户放置。该过程根据一个或更多个字段名称的用户选择以及每个用户选择的字段名称在数据可视化区域中的相应工具架区域中的用户放置来建立视觉规范。在一些实现方式中,数据可视化包括仪表板,该仪表板包括多个不同的部件数据可视化。视觉规范包括多个部件视觉规范,并且每个部件数据可视化基于部件视觉规范中的一个相应的部件视觉规范。在一些实现方式中,由视觉规范定义的数据可视化特征包括标记类型和标记的零个或更多个编码。在一些实现方式中,标记类型是以下中的一者:条形图、折线图、散点图、文本表、或地图。在一些实现方式中,编码选自标记大小、标记颜色、和标记标签。根据一些实现方式,用于生成数据可视化的系统包括一个或更多个处理器、存储器、和存储在存储器中的一个或更多个程序。程序被配置为由一个或更多个处理器执行。程序包括用于执行本文所述的任何方法的指令。根据一些实现方式,非暂时性计算机可读存储介质存储被配置为由具有一个或更多个处理器和存储器的计算机系统执行的一个或更多个程序。一个或更多个程序包括用于执行本文所述的任何方法的指令。因此,提供了用于数据集合的交互式视觉分析的方法、系统、和图形用户界面。附图简述为了对本发明的前面提到的实现方式以及附加实现方式的更好理解,应结合附图对下面的实现方式的描述进行参考,其中相似的参考数字在全部附图中指相应的部分。图1在概念上示出了根据一些实现方式建立数据可视化的过程。图2是根据一些实现方式的计算设备的框图。图3是根据一些实现方式的数据可视化服务器的框图。图4提供了根据一些实现方式的示例数据可视化用户界面。图5示出了根据一些实现方式的具有三个类的简单对象模型。图6示出了根据一些实现方式的具有与另一个类的两种不同关系的单个类。图7a和图7b示出了根据一些实现方式的在四个类之间的关系的蝴蝶结集合以及可以在该上下文中呈现的数据可视化。图8示出了根据一些实现方式的非常简单的对象模型,其中数据可视化是针对单个类而被创建的。图9a-图9c示出了根据一些实现方式建立数据可视化,该数据可视化包括来自没有分层地被嵌套的两个不同类的维度。图10和图11示出了根据一些实现方式的度量的用户选择,度量是在对象模型中的两个或更多个不同类的属性。图12a-图12c示出了根据一些实现方式的分层地在一个或更多个选定维度之上的一个或更多个度量的用户选择以及相对应的数据可视化。图13a-图13d示出了根据一些实现方式的来自在数据模型中的没有在模型中连接的两个或更多个类的度量和维度的用户选择以及可以被生成的相对应的数据可视化。图14a-图14c和图15示出了根据一些实现方式的来自对象模型中的两个或更多个不同的类中的度量(至少一个分层类将它们连接起来)的用户选择以及针对此场景可以被生成的数据可视化。图16提供了根据一些实现方式的用于确定在对象模型中的哪些维度是可达的伪代码描述。图17是根据一些实现方式的用于在数据可视化应用中定义过滤器的用户界面窗口的屏幕截图。图18a-图18c提供了根据一些实现方式的在建立数据可视化时使用对象模型的过程的流程图。图19a和图19b根据一些实现方式提供了对象模型图的两个示例。图19c根据一些实现方式示出了其中并非所有维度都可以从根(root)到达的对象模型图。图19d根据一些实现方式示出了其中从一个节点到另一个节点有两条不同的路径的对象模型图。图20a-图20f根据一些实现方式提供了可用于跟踪销售的雪花(snowflake)示例模式。图21a-图21i根据一些实现方式将图20a-图20f的示例扩展到不是雪花的树。图22a-图22i根据一些实现方式示出了在树的不同分支中具有度量和维度。图23根据一些实现方式提供了关于行项目(lineitems)和订单的简单的模型。图24a-图24e根据一些实现方式示出了使用对象模型来为数据可视化准确地产生计数。图25a-图25c根据一些实现方式示出了使用对象模型来为数据可视化准确地产生总和。图26a-图26d和图27a-图27i根据一些实现方式示出了使用对象模型以在数据可视化中应用过滤器。图28a-图28c根据一些实现方式示出了使用对象模型以在数据可视化中应用多个过滤器。在全部附图中,相似的附图标记指相对应的部分。现在将详细参考其示例在附图中示出的实现方式。在下面的详细描述中,阐述了许多具体细节,以便提供对本发明的透彻理解。然而,对本领域的普通技术人员将明显的是,本发明可在没有这些具体细节的情况下被实践。实现方式的描述交互式数据可视化应用的一些实现方式使用数据可视化用户界面102来建立视觉规范104,如图1所示。视觉规范识别可以在本地存储(例如,存储在显示用户界面102的同一设备上)或者可以在外部存储(例如,存储在数据库服务器上或在云中)的一个或更多个数据源106。视觉规范104还包括视觉变量。视觉变量根据来自数据源106的选定数据字段间接地指定期望数据可视化的特征。特别是,用户向每个视觉变量分配零个或更多个数据字段,并且数据字段的值确定将被显示的数据可视化。在大多数实例中,不是所有的视觉变量都被使用。在一些实例中,一些视觉变量具有两个或更多个所分配的数据字段。在这个场景中,视觉变量的所分配的数据字段的顺序(例如,数据字段由用户分配到视觉变量的顺序)通常影响数据可视化如何被生成和显示。一些实现方式使用对象模型108来建立适当的数据可视化。在一些实例中,对象模型适用于一个数据源(例如,一个sql数据库或一个电子表格文件),但对象模型可以包含两个或更多个数据源。通常,不相关的数据源具有不同的对象模型。在一些实例中,对象模型紧密地模仿物理数据源的数据模型(例如,在对象模型中的类对应于在sql数据库中的表)。然而,在一些情况下,对象模型比物理数据源更规范化(或更不规范化)。对象模型将彼此间具有一对一关系的属性(例如,数据字段)分组在一起以形成类,并识别在类当中的多对一关系。在下面的图示中,多对一关系用箭头示出,每个关系的“多”侧在垂直方向上低于关系的“一”侧。对象模型还将每个数据字段(属性)识别为维度或度量。在下文中,字母“d”(或“d”)用于表示维度,而较后的“m”(或“m”)用于表示度量。当对象模型108被构建时,它可以便于基于用户选择的数据字段来建立数据可视化。因为单个数据模型可以被无限数量的其他人使用,所以为数据源建立对象模型通常被委托给作为关于数据源的相关专家的人。当用户将数据字段添加到视觉规范(例如,间接地通过使用图形用户界面来将数据字段放置到工具架上)时,数据可视化应用222(或web应用322)根据对象模型108来将用户选择的数据字段分组(110)在一起。这种组被称为数据字段集合294。在许多情况下,所有用户选择的数据字段在单个数据字段集合294中。在一些实例中,存在两个或更多个数据字段集合294。每个度量m在确切的一个数据字段集合294中,但每个维度d可以在多于一个的数据字段集合294中。下面参考图10、图11、图13a-图13c、图14a-图14c、图15、图16、和图18a-图18c更详细地描述建立数据字段集合294的过程。数据可视化应用222(或web应用322)针对第一数据字段集合294查询(112)数据源106,且然后生成对应于检索到的数据的第一数据可视化122。根据在视觉规范104中的视觉变量282来构建第一数据可视化122,视觉变量282具有从第一数据字段集合294分配的数据字段284。当只有一个数据字段集合294时,在视觉规范104中的所有信息被用于建立第一数据可视化122。当存在两个或更多个数据字段集合294时,第一数据可视化122基于由与第一数据字段集合294相关的所有信息组成的第一视觉子规范。例如,假设原始视觉规范104包括使用数据字段f的过滤器。如果字段f被包括在第一数据字段集合294中,则过滤器是第一视觉子规范的一部分,并且因此被用于生成第一数据可视化122。当存在第二(或后续)数据字段集合294时,数据可视化应用222(或web应用322)针对第二(或后续)数据字段集合294查询(114)数据源106,且然后生成对应于检索到的数据的第二(或后续)数据可视化124。根据在视觉规范104中的视觉变量282来构建该数据可视化124,视觉变量282具有从第二(或后续)数据字段集合294分配的数据字段284。图2是示出计算设备200的框图,该计算设备200可以执行数据可视化应用222或数据可视化web应用322以显示数据可视化122。在一些实现方式中,计算设备显示数据可视化应用222的图形用户界面102。计算设备200包括台式计算机、膝上型计算机、平板计算机、以及具有能够运行数据可视化应用222的显示器和处理器的其他计算设备。计算设备200通常包括用于执行被存储在存储器214中的模块、程序、和/或指令并从而执行处理操作的一个或更多个处理单元(cpu)202;一个或更多个网络或其它通信接口204;存储器214;以及用于将这些部件互连的一个或更多个通信总线212。通信总线212可以包括在系统部件之间进行互连和控制在系统部件之间的通信的电路。计算设备200包括用户接口206,用户接口206包括显示器208和一个或更多个输入设备或机构210。在一些实现方式中,输入设备/机构包括键盘;在一些实现方式中,输入设备/机构包括“软”键盘,其根据需要被显示在显示器208上,使用户能够“按下”出现在显示器208上的“键”。在一些实现方式中,显示器208和输入设备/机构210包括触摸屏显示器(也被称为触敏显示器)。在一些实现方式中,显示器是计算设备200的集成部分。在一些实现方式中,显示器是独立的显示设备。在一些实现方式中,存储器214包括高速随机存取存储器,例如dram、sram、ddrram或其他随机存取固态存储器设备。在一些实现方式中,存储器214包括非易失性存储器,例如一个或更多个磁盘存储设备、光盘存储设备、闪存设备、或其他非易失性固态存储设备。在一些实现方式中,存储器214包括远离cpu202定位的一个或更多个存储设备。存储器214或可选地在存储器214内的非易失性存储器设备包括非暂时性计算机可读存储介质。在一些实现方式中,存储器214或存储器214的计算机可读存储介质存储下面的程序、模块、和数据结构、或其子集:·操作系统216,其包括用于处理各种基本系统服务和用于执行硬件相关的任务的过程;·通信模块218,其用于经由一个或更多个通信网络接口204(有线或无线)和一个或更多个通信网络(例如互联网、其它广域网、局域网、城域网等)来将计算设备200连接到其它计算机和设备;·web浏览器220(或其他客户端应用),其使用户能够通过网络与远程计算机或设备通信;·数据可视化应用222,其提供图形用户界面102以用于使用户构建视觉图形(例如,单独的数据可视化或具有多个相关数据可视化的仪表板)。在一些实现方式中,数据可视化应用222作为独立应用(例如,桌面应用)执行。在一些实现方式中,数据可视化应用222在web浏览器220内(例如,作为web应用322)执行;·图形用户界面102,其使用户能够通过在视觉上指定元素来建立数据可视化,如下面在图4中所示;·在一些实现方式中,用户界面102包括多个工具架区域250,其用于指定期望数据可视化的特征。在一些实现方式中,工具架区域250包括用于指定数据在期望数据可视化中的布置的列工具架230和行工具架232。通常,被放置在列工具架230上的字段用于定义在数据可视化中的列(例如,视觉标记的x坐标)。类似地,被放置在行工具架232上的字段定义在数据可视化中的行(例如,视觉标记的y坐标)。在一些实现方式中,工具架区域250包括过滤器工具架262,其使用户能够根据选定数据字段来限制所查看的数据(例如,将数据限制到特定字段具有特定值或具有在特定范围内的值的行)。在一些实现方式中,工具架区域250包括用于指定数据标记的各种编码的标记工具架264。在一些实现方式中,标记工具架264包括颜色编码图标270(以基于数据字段来指定数据标记的颜色)、大小编码图标272(以基于数据字段来指定数据标记的大小)、文本编码图标(以指定与数据标记相关联的标签)、和视图级别细节图标228(以指定或修改数据可视化的细节级别);·视觉规范104,其用于定义期望数据可视化的特征。在一些实现方式中,使用用户界面102来建立视觉规范104。视觉规范包括所识别的数据源280(即,指定数据源是什么),其提供足够的信息来找到数据源106(例如,数据源名称或网络完整路径名称)。视觉规范104还包括视觉变量282和每个视觉变量的所分配的数据字段284。在一些实现方式中,视觉规范具有对应于每个工具架区域250的视觉变量。在一些实现方式中,视觉变量也包括其他信息,例如关于计算设备200的上下文信息、用户偏好信息、或未被实现为工具架区域的其他数据可视化特征(例如,分析特征);·一个或更多个对象模型108,其识别数据源106的结构。在对象模型中,数据字段(属性)被组织成类,其中在每个类中的属性彼此间具有一对一的对应性。对象模型还包括在类之间的多对一关系。在一些实例中,对象模型将在数据库中的每个表映射到一个类,在类之间的多对一关系对应于在表之间的外键(foreignkey)关系。在一些实例中,基本源的数据模型不以这种简单的方式干净利索地映射到对象模型,因此对象模型包括指定如何将原始数据转换为适当的类对象的信息。在一些实例中,原始数据源是被转换成多个类的简单文件(例如,电子表格);·数据可视化生成器290,其根据视觉规范来生成并显示数据可视化。根据一些实现方式,数据可视化生成器290使用对象模型108来确定在视觉规范104中的哪些维度从视觉规范中的数据字段可达。对于每个视觉规范,该过程形成一个或更多个可达维度集合292。这在下面在图10、图11、图13a-图13c、图14a-图14c、图15、图16、和图18a-图18c中被示出。每个可达维度集合292对应于数据字段集合294,其除了在可达维度集合292中的可达维度之外通常还包括一个或更多个度量。·可视化参数236,其包含由数据可视化应用222使用的信息,而不是由视觉规范104和数据源106提供的信息;以及·零个或更多个数据库或数据源106(例如,第一数据源106-1),其由数据可视化应用222使用。在一些实现方式中,数据源可以被存储为电子表格文件、csv文件、xml文件、平面文件、json文件、在关系数据库、云数据库、或统计数据库中的表。上面识别的可执行模块、应用、或程序集中的每一者可以被存储在前面提到的存储器设备中的一个或更多个中,并且对应于用于执行上述功能的指令的集合。上面识别的模块或程序(即,指令集)不需要被实现为独立的软件程序、过程、或模块,并且因此这些模块的各种子集可以在各种实现方式中被组合或以其他方式重新布置。在一些实现方式中,存储器214存储上面识别的模块和数据结构的子集。在一些实现方式中,存储器214存储上面未描述的附加模块或数据结构。尽管图2示出了计算设备200,但图2更多地被预期作为可能存在的各种特征的功能描述,而不是作为本文所述的实现方式的结构示意图。在实践中且如本领域中的普通技术人员认识到的,单独示出的项目可以被组合并且一些项目可以被分离。图3是根据一些实现方式的数据可视化服务器300的框图。数据可视化服务器300可以托管一个或更多个数据库328,或者可以提供各种可执行的应用或模块。服务器300通常包括一个或更多个处理单元/核心(cpu)302、一个或更多个网络接口304、存储器314、和用于将这些部件互连的一个或更多个通信总线312。在一些实现方式中,服务器300包括用户接口306,用户接口306包括显示器308和一个或更多个输入设备310,例如键盘和鼠标。在一些实现方式中,通信总线312可以包括在系统部件之间进行互连和控制在系统部件之间的通信的电路(有时被称为芯片组)。在一些实现方式中,存储器314包括高速随机存取存储器,例如dram、sram、ddrram、或其他随机存取固态存储器设备,并且可以包括非易失性存储器,例如一个或更多个磁盘存储设备、光盘存储设备、快闪存储器设备、或其他非易失性固态存储设备。在一些实现方式中,存储器314包括远离cpu302定位的一个或更多个存储设备。存储器314或可选地在存储器314内的非易失性存储器设备包括非暂时性计算机可读存储介质。在一些实现方式中,存储器314或存储器314的计算机可读存储介质存储下面的程序、模块、和数据结构、或其子集:·操作系统316,其包括用于处理各种基本系统服务和用于执行硬件相关的任务的过程;·网络通信模块318,其用于经由一个或更多个通信网络接口304(有线或无线)和一个或更多个通信网络(例如互联网、其它广域网、局域网、城域网等)来将服务器300连接到其它计算机;·web服务器320(例如http服务器),其接收来自用户的web请求,并通过提供响应的网页或其他资源来做出响应;·数据可视化web应用322,其可以由在用户的计算设备200上的web浏览器220下载和执行。一般来说,数据可视化web应用322具有与桌面数据可视化应用222相同的功能,但提供从在具有网络连接的任何位置处的任何设备进行访问的灵活性,并且不需要安装和维护。在一些实现方式中,数据可视化web应用322包括各种软件模块来执行某些任务。在一些实现方式中,web应用322包括为web应用322的所有方面提供用户界面的用户界面模块324。在一些实现方式中,用户界面模块324指定工具架区域250,如上面针对计算设备200所述;·当用户选择期望数据可视化的特征时,数据可视化web应用还存储视觉规范104。上面针对计算设备200描述了视觉规范104及它们存储的数据;·一个或更多个对象模型108,如上针对计算设备200所述;·数据可视化生成器290,其根据用户选择的数据源和数据字段以及描述数据源106的一个或更多个对象模型来生成和显示数据可视化。数据可视化生成器的操作在上面参照计算设备200进行了描述,并且下面在图10、图11、图13a-图13c、图14a-图14c、图15、图16、和图18a-图18c中被描述;·在一些实现方式中,web应用322包括建立并执行查询以从一个或更多个数据源106检索数据的数据检索模块326。数据源106可以在本地存储在服务器300上,或者存储在外部数据库328中。在一些实现方式中,可以融合来自两个或更多个数据源的数据。在一些实现方式中,数据检索模块326使用视觉规范104来建立查询,如上面针对图2中的计算设备200所述;·一个或更多个数据库328,其存储由数据可视化web应用322或数据可视化应用222使用或创建的数据。数据库328可以存储提供在所生成的数据可视化中使用的数据的数据源106。每个数据源106包括一个或更多个数据字段330。在一些实现方式中,数据库328存储用户偏好。在一些实现方式中,数据库328包括数据可视化历史日志334。在一些实现方式中,历史日志334跟踪每次数据可视化再现数据可视化。数据库328可以以许多不同的格式存储数据,并且通常包括许多不同的表,每个表具有多个数据字段330。一些数据源包含单个表。数据字段330包括来自数据源的原始字段(例如,来自数据库表的列或来自电子表格的列)以及可以从一个或更多个其他字段计算或构建的派生数据字段。例如,派生数据字段包括从日期字段计算月或季度、计算在两个日期字段之间的时间的跨度、计算定量字段的累积总数、计算百分比增长等。在一些实例中,派生数据字段通过在数据库中所存储的过程或视图访问。在一些实现方式中,派生数据字段330的定义与数据源106分开地被存储。在一些实现方式中,数据库328存储每个用户的用户偏好的集合。当数据可视化web应用322(或应用222)做出关于如何查看数据字段330的集合的建议时,用户偏好可以被使用。在一些实现方式中,数据库328存储数据可视化历史日志334,其存储关于所生成的每个数据可视化的信息。在一些实现方式中,数据库328存储其他信息,包括由数据可视化应用222或数据可视化web应用322使用的其他信息。数据库328可以与数据可视化服务器300分离,或者可以与数据可视化服务器包括在一起(或者两者)。在一些实现方式中,数据可视化历史日志334存储由用户选择的视觉规范104,视觉规范104可以包括用户标识符、当数据可视化被创建时的时间戳、在数据可视化中使用的数据字段的列表、数据可视化的类型(有时被称为“视图类型”或“图表类型”)、数据编码(例如,标记的颜色和大小)、所选择的数据关系、以及什么连接器被使用。在一些实现方式中,每个数据可视化的一个或更多个缩略图图像也被存储。一些实现方式存储关于所创建的数据可视化的附加信息,例如数据源的名称和位置、来自在数据可视化中包括的数据源的行的数量、数据可视化软件的版本等。上面识别的可执行模块、应用、或程序集中的每一者可以被存储在前面提到的存储器设备中的一个或更多个中,并且对应于用于执行上述功能的指令集。上面识别的模块或程序(即,指令集)不需要被实现为独立的软件程序、过程、或模块,并且因此这些模块的各种子集可以在各种实现方式中被组合或以其他方式重新布置。在一些实现方式中,存储器314存储上面识别的模块和数据结构的子集。在一些实现方式中,存储器314可以存储上面未描述的附加模块或数据结构。尽管图3示出了数据可视化服务器300,但图3更多地被预期作为可能存在的各种特征的功能描述,而不是作为本文所述的实现方式的结构示意图。在实践中且如本领域中的普通技术人员所认识到的,单独示出的项目可以组合并且一些项目可以被分离。此外,上面关于服务器300示出的一些程序、功能、过程、或数据可以在计算设备200上被存储或执行。在一些实现方式中,功能和/或数据可以在计算设备200和一个或更多个服务器300之间进行分派。此外,本领域中的技术人员认识到,图3不必表示单个物理设备。在一些实现方式中,服务器功能跨越包括服务器系统的多个物理设备进行分派。如在本文所使用的,对“服务器”或“数据可视化服务器”的提及包括提供所描述的功能的服务器的各种组、集体、或阵列,并且物理服务器不必物理地并存(例如,各个物理设备可以遍布全美国或遍布全世界)。图4示出了根据一些实现方式的数据可视化用户界面102。用户界面102包括也被称为数据窗格的模式信息区域410。模式信息区域410提供可以被选择并用于建立数据可视化的所命名的数据元素(例如,字段名称)。在一些实现方式中,字段名称的列表被分成一组维度和一组度量(通常是数字量)。一些实现方式还包括参数的列表。图形用户界面102还包括数据可视化区域412。数据可视化区域412包括多个工具架区域250,例如列工具架区域230和行工具架区域232。这些也被称为列工具架230和行工具架232。此外,该用户界面102包括过滤器工具架262,过滤器工具架262可以包括一个或更多个过滤器424。如这里所示的,数据可视化区域412还具有用于显示视觉图形的大空间。因为在此图示中还没有数据元素被选择,所以空间最初没有视觉图形。用户选择一个或更多个数据源106(其可以存储在计算设备200上或远程地被存储),从数据源选择数据字段,并使用所选择的字段来定义视觉图形。数据可视化应用222(或web应用322)在数据可视化区域412中显示所生成的图形122。在一些实现方式中,用户提供的信息被存储为视觉规范104。在一些实现方式中,数据可视化区域412包括标记工具架264。标记工具架264允许用户指定数据标记的各种编码426。在一些实现方式中,标记工具架包括颜色编码图标270、大小编码图标272、文本编码图标274、和/或视图级别细节图标228,其可用于指定或修改数据可视化的细节级别。对象模型可以被描绘为以类作为节点以及它们的多对一关系作为边的图形。如在本文所示,这些图形被布置成使得每个关系的“许多”侧总是在“一侧”之下。例如,在图5中,办公室类502具有与公司类504的多对一关系512,以及办公室类502还具有与国家类506的多对一关系514。在该图形中,公司可以有多个办公室,以及国家可以有多个办公室,但各个办公室属于单个公司和国家。图5中的对象模型被连接,但不是所有的对象模型都被连接。通常,数据源106的对象模型108被预先建立。当用户稍后建立数据可视化时,对象模型108的结构有助于生成适当的数据可视化。通常,任何一对类通过关系图由至多一条路径关联(join)。当多条路径是可能的时,用户可能需要指定使用哪条路径,或者将数据集列转行以将两条路径组合为一条。下面的图中的一些示出了各种对象模型,并示出了在对象模型中的维度d和度量m的用户选择。基于在对象模型内的维度和度量的位置,数据可视化生成器290确定要生成多少不同的数据可视化以及要建立什么。在这个上下文中,定义从对象模型中的另一个数据字段可达的维度的概念是有用的。特别地,当存在从包含数据字段的类开始并以包含维度的类结束的多对一关系的序列时,维度d是从该数据字段可达的。此外,如果维度d在类c中,则维度d是从类c中的所有其他数据字段可达的。在这种情况下,存在以数据字段开始并以维度结束的零个多对一关系的序列。在有“可达”的这个定义的情况下,可以定义从图形中的给定节点可达的维度集合。特别是,对于在视觉规范104中的每个数据字段(维度或度量),维度的可达集合292是在视觉规范中的在与给定数据字段相同的细节级别(lod)处的所有维度,或是通过从数据字段向上遍历图形可达的所有维度。对于每个数据字段,识别可视化过滤器的可达集合也是有用的。这包括在可达的维度上的所有过滤器。注意,度量过滤器可以在适当的细节级别处隐含地被视为维度过滤器。图16提供了用于确定在对象模型中的每个数据字段(维度或度量)的可达维度的伪代码查询。对于每个数据字段,可达维度和可达过滤器的集合形成以数据字段为中心的隐式雪花模式。这意味着有一种定义明确且独特的方式来将过滤器应用于数据字段并聚合度量。显示每个数据字段的查询的结果本身使解释结果变得容易。除了使用户建立期望可视化变得更容易之外,使用可达维度还可以提高数据检索的性能。查询更快,因为它们只必须加入通过多对一关系可达的维度。这可以被理解为主动联合剔除行为的一般化形式。查询只必须涉及创建期望可视化绝对必需的表。对于使用n个数据字段的数据可视化,该过程可以导致n个不同的查询的理论最大值。然而,这些查询中的许多是冗余的。一个查询的结果可以被包含在一个或更多个其他查询的结果中。此外,可以组合计算在相同的细节级别处的度量的查询。因此,这个过程通常运行较少的查询。从性能角度来看,通过多对多关联来生成多个独立查询而不是单个整体查询还具有额外的优点:查询可以并行地运行。由于此,一些实现方式能够在所有查询返回它们的结果之前开始再现数据可视化。给定上述查询语义,存在出现的两个主要挑战:多个细节级别和多个域。首先,独立查询可以产生在不同的细节级别处的结果。如果细节级别嵌套(例如(州、城市)与州),这不是特别成问题的。该过程可以简单地将较粗略的lod值复制到较精细的lod。当lod部分地重叠(例如(州、城市)和(州、zip))或是不相交的(disjoint)(例如(州、城市)和(产品、子产品))时,更具挑战性。其次,独立查询可能产生具有不同域的结果。例如,计算每州的sum(人口)可能为50个州中的每个州返回条目(如果人口表对美国是完整的)。然而,计算每州的sum(销售额)只返回有销售交易的州。如果销售表不包括在10个州中的交易,那么查询将只返回40个州的结果。为了处理多个细节级别,该过程通过以在相同细节级别处的查询结果组合到聚合结果表中来开始。该过程还组合嵌套查询结果(在严格子集/超集lod关系中的那些结果)。这导致嵌套结果的重复,但并不是有害的,因为它允许比较总计与小计。即使在将所有这些情况组合在一起之后,当细节级别部分地重叠或不相交时,仍然存在具有多个结果表的实例。在这些实例中,实现方式使用用于可视化结果的各种方法。除了处理多个细节级别以外,实现方式也处理其他场景。存在实例,其中数据字段具有值的两个或更多个不同的域。例如,所有州的集合可以不同于具有订单的州的集合,其可能不同于具有雇员的州的集合。对象模型允许单个逻辑概念(例如,“州”)具有与它相关联的多个域。另一种场景是当有多个根(“事实”)表时。多个事实表的存在可引入多对多关系和复制(重复)。此外,多个事实表可以改变关联(join)如何被实现。在许多情况下,可以通过像树一样展现关联来查询具有雪花结构的单个事实表。然而,在有多个事实表的情况下,存在关于将哪个表指定为雪花的中心的固有模糊性,并且以这种方式在表中关联可能不是用户的数据模型的良好可视化。当一个表具有对同一表(及其子树)的两个或更多个引用时,另一种场景出现。例如,考虑每个订单包括orderdate和shipdate的场景。存在这个数据可以被构造的各种方式。在第一种情况下,orderdate和shipdate都是在订单表本身中的数据字段。在这种情况下,数据很容易查询。在第二种情况下,有单独的orderdate和shipdate表,因此在订单表和这些不同的表中的每个之间有单独的关联。在第三种情况下,orderdate信息和shipdate信息被合并到单个日期表604中,如图6所示。在这种情况下,存在对应于订单日期的行的第一子集606(例如,具有“订单”的日期类型)以及对应于装运日期的行的第二子集608(例如,具有“装运”的日期类型)。在这种情况下,订单表602具有到同一日期表的两个关联:到表示订单日期的行的第一关联616和到表示装运日期的行的第二关联618。在类或数据库表之间的关系也可以具有“蝴蝶结”布置。图7a中的可视化使用机会数量、案例持续时间、产品、和客户名称。为了显示该信息,使用都具有对应于产品702的行的两个所链接的数据可视化704和706。这利用具有如图7b所示的数据模型(或对象模型)的融合。事实表factcase722和factopportunity724中的每一个具有与维度表dimaccount712和维度表dimproduct728的独立关系。这四种关系730看起来像蝴蝶结。用通俗语命名的“蝴蝶结”是两个事实表都可以与两个维度表相关联的理念,这在它们的关系中强加交叉。一些实现方式还处理使“平面(flat)”表标准化。例如,数据源(例如数据仓库)可以包括表示多个概念类的数据。一些实现方式使用众所周知的标准化技术来建立表示有意义的类的对象模型。在每个对象模型图中,当前视觉规范104的维度和度量的源被标记为“d”和“m”。在最简单的情况下,有包括来自当前视觉规范104的所有维度和度量的单个类,如图8所示。在这种场景下,度量和维度来自同一个类,且计算语义是微不足道的。该过程将度量上卷到维度细节级别。这导致包含维度和聚合度量的单个表。为这个结果表创建小的多重布局不一定是明显的,因为在单个类中的属性之间没有模型化关系。然而,工具架模型(行232和列230)提供一组启发法来处理此。在同一工具架上的维度(dimensions)创建分级轴(例如,如图9b所示),而在不同工具架上的维度(dimensions)创建交叉轴。在同一轴上的多个度量被链接(如由图7a中的两个列704和706所示的)。其他工具架用于创建标记和定义它们的视觉外观。在雪花模型中,度量来自单个类,如图9a所示。维度来自通过从度量的类向上遍历关系图可达的相同的一个或更多个类。该过程沿着关系边将维度关联到度量类的类。度量被一直聚合到维度细节级别。所有其他类被忽略。例如,在图9a中,所有的度量来自订单表904,并且数据可视化具有在产品类902和区域类908中的维度。在产品类902和区域类908中的维度定义用于聚合来自订单类904的度量的细节级别。在该示例中,没有来自州类906的数据可视化的维度或度量,因此它的数据不被使用。然而,在查询中可能需要州类906,以便将来自订单类904的度量连接到区域类908。对象模型指示在维度之间是否存在嵌套关系或交叉关系,这在一些实现方式中用于确定默认行为。在图9a的示例中,产品和区域是相互独立的,所以它们应该在小的多重布局中交叉,而不管它们是否在同一个轴上。然而,一些实现方式使用户能够超驰默认行为。例如,即使当模型显示在独立维度之间的交叉关系时,用户也可能想要纯粹基于由实际数据值定义的关系来嵌套。相反,即使嵌套有意义,用户也可能想要显示交叉可视化,并引入空白区,其中在嵌套维度之间没有相对应的配对。在同一轴上显示交叉维度在图9b中被示出。在这种情况下,用户将两个独立的维度段920和类别922放置在同一个工具架(列工具架230)上。用户将度量销售额924放置在行工具架232上,其在这里使用count()进行聚合。段和类别维度是独立的,因此默认地它们是交叉的。顶部列头部940列出段,而下部列头部942列出类别。由于交叉,每个类别是针对每个段被显示,且这将出现,即使没有一些段/类别组合的数据。在一些实现方式中,用户界面102处理用户交互以处理交叉。例如,在一些实现方式中,选择在交叉轴中的一个头部(例如,第一家具头部926)导致选择所有相应的数据(例如,具有相同家具类别的所有列的家具数据930、932和934)。在一些实现方式中,当在不同轴上存在嵌套维度时,显示使用替代技术来仅示出相关组合,如图9c所示。在这种情况下,数据字段“子类别”嵌套在数据字段“类别”下,且这两个数据字段在不同的轴上。每个类别的子类别是完全不同的(例如,在家具类别中的书架和椅子,但在办公用品类别中的电器、艺术品、和活页夹)。由于此,对于在数据可视化中的每一行,显示包括单独的一组列头部。有时这被称为网格图。它确保每个子类别只显示在适当的类别中。融合是雪花情况的一般化,其中度量可以来自多个类。这在图10中被示出。维度通过单个类(有时被称为“关联lod”)是从所有度量可达的。在图10中,州类1004是“关联lod”。如果每个度量被单独地考虑,这个场景与雪花相同。每个度量可以独立地上卷到维度lod。然后,聚合的度量可以在维度lod处关联在一起。例如,根据在区域类1008中的维度来聚合来自订单表1002的度量,并且也根据在区域类1008中的维度来聚合来自供应商类1006的度量。因为来自订单类1002和供应商类的度量在同一细节级别处被聚合,所以结果集可以直接被关联以在维度lod处形成单个表。如果数据可视化没有维度(例如,它显示总计),那么它是微不足道的融合情况,因为所有(零)维度可以从任何度量来达到。在这种情况下,所有的度量上卷到空维度lod(即,一个聚合数据值针对每个度量被计算),并且聚合值显示在单个可视化中。这即使在对象模型没有被连接时也起作用。可以放宽所有维度通过同一个类可达的限制。只要所有维度是通过向上遍历图形从所有度量可达的,该过程就可以使用与标准融合相同的查询语义和视觉布局。这在图11中被示出,其将产品类1110添加到图10中所示的数据模型。在该示例中,尽管没有经历单个关联lod,来自订单1002和供应商1006的度量可以根据在区域类1008和产品类1110中的维度被上卷。注意,彼此间的维度关系(交叉或嵌套)与所使用的度量集合无关,因此小多重显示的布局可以如同简单融合一样使用相同的规则。有时度量可以被定义在对象模型的维度之上,如图12a所示。在这种情况下,在区域类1208(也许人口)中的度量将根本不被聚合。替代地,度量将作为属性被复制(拷贝)到维度lod(根据在订单类1202和产品类1210中的维度)。实际上,数据可视化应用将这个度量视为仅仅另一个维度。为了使这个行为对用户变得清楚,一些实现方式抑制在行工具架232或列工具架230上的相对应的球粒(pill)的聚合功能,如图12c所示。不是显示sum(利润)1250,用户界面显示利润1252。在一些实现方式中,用户界面以其他方式改变表达的体现,例如在视觉上不再强调它。此外,一些实现方式在视觉上确认在选择中的重复,例如在交叉轴中的重复头部。例如,在图12b中,在数据可视化中的所有行1230显示类别销售额的相同值(只有一个数据值),并且这些行在被查看时一起被加亮。当不是所有维度是从所有非属性度量可达的时,更具挑战性的细节级别问题出现。例如,考虑图13a中的对象模型,其具有公司类1302和国家类1304,但没有在它们之间定义的关系。这并不像它可能看起来的那么奇怪,因为在对象被使用之前,用户不必定义在两个对象之间的关系。在一些实现方式中,这导致两个垂直地链接的数据可视化1322和1324,如图13b所示。在一些实现方式中,两个不同的数据可视化水平地链接,如图13c和图13d所示。在图13c中,两个可视化1332和1334的顶部水平地对齐。在图13d中,两个数据可视化1342和1344的底部水平地对齐。注意,图13c和图13d中的图不共享一个轴。在一些实现方式中,当有多个数据可视化时,一次显示一个可视化,允许用户浏览它们。为了帮助用户理解哪些字段用于产生可视化,当相对应的可视化没有显示或没有焦点时,一些实现方式使未使用的字段或过滤器变为灰色。在一些实例中,通过多对多关系来链接维度和度量,如图14a所示。在该示例中,来自客户类1402的维度和度量通过多对一关系与州类1406连接。类似地,来自公司类1404的维度和度量通过多对一关系与州类1406连接。这种情况与融合非常相似,不同之处在于维度包括自两个底部类1402和1404。结果是来自公司类1404的维度不是从客户类1402中的度量可达的,反之亦然。这种情况类似于图13a中的断开图情况,不同之处在于附加的州类1406被添加。在一些场景中,一些实现方式组合融合和断开行为,嵌套在州中,显示关于客户和公司的独立的数据可视化,如图14b所示。如图14b所示,州维度从客户类1402和公司类1404都是可达的,因此整体可视化通过州1420对齐。例如,图14b中的部分数据可视化显示阿拉巴马1422和亚利桑那1424的数据。在一个州的每个水平区域内,有公司1426的列表,与视觉标记1428一起表示每个公司的销售额。此外,每个水平州区域还具有客户名称1430的列表,与视觉标记1432(例如,条)一起表示这些单独的客户中的每一个客户的利润。这示出了基于来自州类1406的共享维度的部分对齐。图14c示出了一些实现方式使用来自图14a所示的相同对象模型的数据字段的不同选择来创建的数据可视化。对于图14c,用户从客户类1402选择度量销售额,并且也从公司类1404选择度量销售额。然而,用户尚未从这两个类中的任一个选择任何维度。因为维度州是从所有度量可达的,所以存在单个数据可视化,每个度量上卷到州。然而,在有这两个事实表和有限销售额的情况下,出现关于要显示哪些州的问题。在一些实现方式中,默认行为是执行完全外关联,显示每个州,以及每个州的公司销售额和客户销售额(空白指示零)。例如,在图14c中,阿拉巴马没有公司或客户的销售额1450。另一方面,加利福尼亚具有公司销售额1452和客户销售额1454。一些州只有一个或另一个,例如佛罗里达只有公司销售额1456,而伊利诺伊只有客户销售额1458。在一些实现方式中,用户可以选择显示什么数据(例如,省略没有来自客户类1402或公司类1404的数据的州)。在一些实现方式中,没有公司或客户的活动的州默认地被省略。图15示出了与图14a相同的场景,不同之处在于来自州类1506的维度被省略。由于对象模型,已知客户类1502和公司类1504通过州类1506具有多对多关系。然而,用户没有请求将州包括在可视化中。在这种场景下,一些实现方式简单地忽略贯穿州的链接,并产生与在断开的场景中相同的可视化(图13a-图13d)。这种方法具有下面的优点:从在数据可视化中没有州到使州被包括的过渡有些自然。用户以两个独立的列表开始,然后添加州将为每个州创建两个独立的列表。一些实现方式以另一种方式处理这种场景。一些实现方式产生单独的可视化,但自动加亮在州上的链接行为。在一些情况下,这是有意义的。例如,如果客户可由在同一州中的公司服务,那么点击在客户列表中的客户将加亮在他们的州中的可以为他们提供服务的公司。相反,点击公司将加亮他们可以服务的客户。另一方面,当没有这种有趣的语义时,加亮在与一些客户相同的州中的公司可能是分散注意力的或招致反效果的默认行为。这种类型的交叉加亮也可能是在计算上昂贵的,因此使它成为默认行为对于在具有有限计算资源的设备上的实现方式是不切实际的。基于这些示例,一些实现方式基于选定的维度和度量以及相对应的对象模型来执行下面的步骤。首先,该过程通过从每个度量可达的维度集合来划分在视觉规范104中的度量(创建一个或更多个可达维度集合292)。其次,对于可以达到同一维度集合的每个度量集合,该过程将度量上卷到维度细节级别。每个可达维度集合292与它的对应度量一起形成数据字段集合294。第三,该过程使用与在数据字段集合中的维度和度量相关联的视觉变量映射来为每个数据字段集合294创建单独的数据可视化。该过程忽略所有其他映射。一些实现方式也处理图14b所示的情况。在这种情况下,有在州内嵌套的独立的客户和公司列表。在这种情况下,将单独的可视化嵌套在公共维度中是有用的。类似的场景出现,其中将一组度量显示为与另一度量集合的显示的边缘交错的或在另一度量集合的显示的边缘中的小计或总计是有用的。一些实现方式通过将用户限制到上面的更容易的场景之一来防止用户进入具有多个可视化的场景内。例如,一些实现方式通过要求用户为每个图表选择“关联lod”对象且然后禁用通过从关联lod向上沿着图形走而不可达的维度以及通过向下沿着树走而不可达的度量来将用户限制到融合场景。在融合中,多对一关系走的路线并不总是清楚的。当多对一关系走预期的路线时,融合给出正确和有用的结果。当它不按预期的走时,“*”被显示。一些实现方式对这里的对象模型问题采取类似的方法。例如,不是制作独立的列表,一些实现方式显示列表的叉积并复制度量。这在下面更详细地被描述。过滤器如何适用与域问题密切相关。过滤器应该明确地向下沿着关系图形(从一个到多个)应用。在图5的对象模型中,在公司上的过滤器也应该应用于办公室。向上沿着图形过滤(例如,如果过滤器移除在英国的所有办公室,英国也应该被过滤吗?)是更有问题的。在一些实现方式中,每个过滤器具有指定的lod,并且其在该细节级别处被应用。在一些实现方式中,当上述过程导致两个或更多个不同的数据可视化时,该过程执行所有聚合结果集合的自然关联以产生单个交叉结果表。这个聚合体是单个表,所以它可以用通常的方式展现。这是数据融合的扩展形式,如下面更详细地描述的。这种方法复制数据,但复制发生在聚合之后,因此不太可能在分析上是错误的。为了帮助用户理解特定字段如何被计算,当用户点击在工具架区域中的球粒时,一些实现方式使从该球粒中不可达的所有字段变灰和过滤掉。例如,球粒的悬停文本指示“sum(销售额)针对每个州被计算,按装运日期进行过滤(1个维度和2个过滤器未被使用)”。这种方法可能复制大量数据。这可能导致大量数据标记,其可能引起渲染性能问题。然而,在所有计算完成之后完成复制,因此查询时间不受影响。数据的复制可能对用户引起一些困惑。一些实现方式通过为用户交互地加亮在可视化中的复制的数据来解决这个问题。可选地,一些实现方式避免在已知数据被复制时自动堆叠数据。当查看数据时,一些实现方式显示单独的结果集以帮助用户理解每个数据点的细节级别。一些实现方式将数据融合与对象模型组合,以用于建立数据可视化。数据融合是特别的数据集成特征,其允许用户容易连接到多个不同的数据源,并建立使用来自所有数据源的数据的可视化。当相关数据可能存储在不同的位置(例如tableau服务器、公司数据仓库、电子表格文件、和csv文件)上时,这使用户能够回答常见的业务分析问题。数据融合消除了在主数据源和辅助数据源之间的区别。在数据融合中,在主数据源和辅助数据源之间没有用户可见的区别。这个对称性的一个重要暗示是,用户将能够将数据源的“链”融合在一起(例如,a与b融合,b与c融合),允许非星形模式的创建。数据融合提供了完整的外关联语义,而不是被限制到在主数据源和所有辅助数据源之间的左关联语义。因此,分析的域不被在主数据源中的条目集合限制。在数据融合中,默认情况是总是显示来自所有数据源的所有数据。用户能够通过在数据源关系中的过滤器和/或设置来控制这种行为。此外,相关字段可互换地被处理,始终显示整个合并域,而不管它来自哪个数据源。例如,如果在州数据字段上关联两个不同的表,则来自任一表的州数据字段可以以相同的方式被使用。如果用户想要将域限制到输入数据源之一,他们可以将相关字段放在过滤工具架上,并获得特殊的过滤对话选项,其允许多重选择对域有贡献的数据源。数据融合消除了在模式查看器中管理链接状态的需要。在模式查看器中的链接允许用户控制融合数据源被关联时的细节级别。在数据融合中,由于外关联语义,消除了对每图表链接图标的需要。用户仍然需要指定数据源关系,但关于此的ui使这变得更容易。数据融合支持在各处的所有计算和数据建模概念。所有计算对所有数据源起作用,因为没有在数据融合中被指定为主要数据源的源。特别是,非加性聚合(例如countd和median)对所有数据源起作用;来自所有数据源的维度使用行级数据来划分视图(attr聚合未被默认地使用);跨数据源计算对行级数据起作用,并可用作维度;对来自所有数据源的数据进行地理编码,且结果可用作在可视化中的维度;以及集合、组、仓、组合字段、和lod表达式一致地起作用,不管它们来自哪个数据源。数据融合提供了丰富的数据源关系。在数据融合中,用户可以在地理编码结果上融合(且在一些实现方式中用户可以与表计算融合)。此外,用户可以指定更丰富的一组关系运算符(例如空间包含)连同更标准的运算符(例如<和≠)。将数据融合的特定过程与在数据集成中执行的关联进行比较是有用的。存在与数据融合相关的数据集成的至少三个部分。首先,数据集成语义通常要求关联出现在数据处理管线(pipeline)的开始处。这有许多不希望有的结果,这些不希望有的结果最好用数据融合来解决。数据集成的用户体验在数据建模工具中开始。用户必须做出复杂的决定,比如在他们的数据源中要包括哪些数据库表,以及在他们可看到他们的数据之前要使用哪些关联类型。相反,数据融合允许用户递增地建立他们在他们的分析中使用的表的集合,并仅在必要时定义关系。一些实现方式甚至为它们推断出一些默认关系。数据融合的这一方面在一些实现方式中是默认体验。用户只必须在罕见场景中定义特定的关联,其中例如关联的复制行为实际上是可取的。在聚合之前的关联复制数据,这常常使聚合变得不准确。这有时可以使用lod表达式以撤销复制来避免。另一方面,在数据融合中,在聚合之后的关联的行为解决了宽得多的范围的分析场景,且是更好的默认。此外,在聚合之后执行关联通常有效得多。关联改变用户的数据。内、左、和右关联过滤输入数据,改变用户的数据的域。左、右、和外关联将null引入到字段中,这也可能是非常令人困惑的,尤其是如果在数据中已经有null。通过将关联延迟到在管线中的较后部分并且通过不使关联的细节暴露于用户,数据融合具有默认地提供更好的行为的灵活性。由于上述原因,一些实现方式提供用户界面,其中融合语义是默认的。在数据源定义中指定具体的关联是允许的,但这将成为高级的场景以涵盖数据集成使用情况的一小部分。比较数据集成与数据融合的第二种方式是在数据准备窗口中的关联图ui。数据融合的一些实现方式利用相同的基本关联图。比较数据集成与数据融合的第三种方式是关于数据联合。数据融合的一些实现方式使用数据联合。这意味着融合计算可以被移动到联合被执行的地方(例如,tableau数据引擎)。在数据融合中,所有数据源基本上像“主要”数据源一样表现。这种设计的一个重要暗示是,当在来自多个数据源的维度之间存在多对多关系时,数据可视化生成器290可以在视觉上跨越多个标记复制度量。这是预期的。事实上,这确切地是lod表达式工作的方式。如果两个lod表达式计算比可视化lod更粗略的聚合,则它们中的每一个跨越所有标记被复制。要注意的一个重要点是,在有融合语义的情况下,关联可能引入复制标记,但聚合值仍然是有意义的。相反,在数据集成中的关联首先复制数据,经常导致无意义的聚合值和复制标记。因此,融合语义是默认行为。地理编码可以首先应用于两个表以允许在从地理编码产生的空间类型上的融合。这被视为在任何其他计算上的融合。在数据融合之后应用致密化。使用完全外关联语义避免了首先应用致密化的需要,因为所有数据从两个数据源被拉出。当使用数据融合时,所有相关的字段具有代替“使用全部”选项的“使用选定数据源(useselecteddatasources)”选项1702,如图17所示。在这里,用户可以特别选择应该合并哪些数据源域来产生相关字段的域。关于相关字段的通用过滤器在行级别处应用于在相关字段的域(其为输入字段域的并集)上的所有相关表。关于相关字段的条件和前n个过滤器像在包含在排序计算中使用的字段的表上的非相关字段过滤器一样被处理。关于非相关字段的过滤器总是在行级别处被应用于源表。关于非相关字段的过滤在源表上被计算,且然后该表被上卷到相关字段级别以获得通过过滤器的相关字段域。该过滤器然后被应用来移除没有通过过滤器的值。重要的是,它不被用于移除存在于相关表中但不存在于源表中的值。一些实现方式生成用于数据库查询的查询树。在高级别处,一些实现方式使用下面的模式来生成关于可视化的查询:·将数据源过滤器应用于每个数据源。·评估数据源特定的计算,包括地理编码。·使用所定义的融合关系来创建跨越过滤数据源的关联树。默认地使用在用户没有明确地指定不去的任何地方的外关联。在树中的必要的地方插入跨数据源计算的评估(如果跨数据源计算用作关系字段,则它需要在关联树的中间被评估)。平等相关的字段被合并成单个字段。·应用维度过滤器。重要的是,未明确地排除“不匹配”值的过滤器被假定为保留它们。·对于每个数据源,从该数据源选择数据关系字段和可视化维度的不同组合。结果是从数据源的关系字段(“关联lod”)映射到可视化的lod的表。·将该表关联回到相对应的数据源,并应用“groupby”来将结果上卷到可视化lod。所有聚合直接从行级别上卷到可视化lod。·将在可视化lod列上的所有因而得到的表关联在一起以产生可视化数据表。·应用度量过滤器,其后是标准查询管线的其余部分。对于lod表达式、带有聚合条件的过滤器或前n个过滤器,生成复制上述树的片段的子查询。虽然上面的模式指定了建立关于任何融合场景的查询树的一般过程,但将此转换为有效得多的形式的另外的优化可以被应用。为了实现优化,一些实现方式包括跟踪在每个表中的数据字段之间的函数依赖的元数据。在一些实现方式中,该信息从在数据源中的主键信息或从所计算的字段关系可得到。对于所提取的数据集,一些实现方式以前在提取期间分析了该表,并使该元数据对查询管线变得可用。一些实现方式还使用包含依赖,例如主键/外键信息。对于来自同一个sql连接的表,一些实现方式从数据库元数据获取该信息。在其他情况下,用户提供此信息。一些实现方式从过去的查询,例如从数据可视化历史日志334,学习这些元数据属性。在一些实现方式中,数据融合使用联合而不是进行融合作为在数据解释器中的特殊情况阶段。数据融合被实现为aql(分析查询语言)逻辑树,其使用查询管线(带有一些适当的优化扩展)被编译成联合树。在一些实现方式中,联合树最终主要在tableau数据引擎中被执行。为了使空间分析场景变得可能,一些实现方式也将地理编码移动到tableau数据引擎。一些实现方式包括各种性能优化。在一些实现方式中,该方法包括:·跨越细节级别划分min/max/sum/count,使得这些聚合可以在第一次查询中被请求,而不需要第二次通过。·如果包含依赖是已知的,则不增加域的大小的完全外关联可以被简化或移除。·如果一些函数依赖是已知的,那么这个过程可以避免不做任何事情的上卷。·一些现有的优化可以被推广。特别是,过滤器下推可以提高性能。融合的一个假设是,过程可以创建将数据源的行级别数据映射到在视图中的维度(例如标记集合)的表。这在数据融合的一些实现方式中有时被称为“关联表”。为了在数据融合中为所有数据源启用主表行为,该过程向具有在进行中的聚合的每个数据源发送相应的关联表。在概念上,关联表从数据源的相关列映射到在数据可视化中的起作用的维度。这可以通过替代地创建从相关列映射到标记索引的表来被简化(例如,维度值的每个组合的唯一整数)。这避免了向数据源发送维度的需要。维度值可能是长的,导致复杂的查询。而且如果维度值是字符串(这是常见的),则该过程在数据源之间移动数据时可能遇到整理问题。标记索引避免了这些问题。给定从相关列映射到标记索引的关联表,该过程可以用多种方式将它关联到远程数据库。如果相关列在功能上确定标记索引(这是最常见的场景),那么只要没有太多的情况,该过程就可以将关联转换成简单情况表达式。如果相关列不在功能上确定标记索引,那么只要数据库支持表文字(tableliteral)(例如,sqlserver或postgres)并且在表中没有太多的行,该过程就可以将关联表转换成表文字。该过程可以在远程数据库上创建临时表,并在此与其关联。这只有在用户具有创建临时表的权限时才起作用。最后,该过程可以将远程数据源拉入tableau数据引擎内,并在此进行关联。图18a-图18c提供根据一些实现方式的用于生成(1802)数据可视化的过程1800的流程图。该方法在具有一个或更多个处理器和存储器的计算设备200处被执行(1804)。存储器存储(1806)被配置为由一个或更多个处理器执行的一个或更多个程序。该过程接收(1808)视觉规范104,视觉规范104指定一个或更多个数据源106、多个视觉变量282、和来自一个或更多个数据源106的多个数据字段284。多个视觉变量282中的每个与相应的一个或更多个数据字段284相关联(1810),并且这些分配的数据字段284中的每个是维度d或度量m。通常,视觉规范104包括(1812)不与来自一个或更多个数据源106的任何数据字段330相关联的一个或更多个附加视觉变量。在一些实现方式中,每个视觉变量282是(1814)以下中的一者:行属性、列属性、过滤器属性、颜色编码、大小编码、形状编码、或标签编码。对于数据字段的每个度量m,该过程识别(1816)相应可达维度集合r(m)292,该相应可达维度集合r(m)292由数据字段的根据在一个或更多个数据源的预定义对象模型中的多对一关系的序列从相应度量m可达的所有维度d组成。序列可具有长度0,表示维度和度量在同一类中的情况。在一些实现方式中,当维度d和度量m在预定义对象模型中的同一类中时,或者,度量m是在预定义对象模型中的第一类c1的属性,维度d是在对象模型中的第n类cn的属性,且n≥2,并且在预定义对象模型中存在零个或更多个中间类c2,…,cn-1的序列,使得对于每个i=1,2,…,n-1,在类ci和ci 1之间存在多对一关系时,维度d是从度量m可达的(1820)。对于每个不同的可达维度集合r292,该过程形成(1822)数据字段的相应数据字段集合s294,其中s由在r中的每个维度和数据字段的满足r(m)=r的每个度量m组成。对于数据字段集合s294中的每个(1824),该过程生成相应的数据可视化。首先,对于在相应数据字段集合s中的每个度量m,该过程将度量m的值上卷(1826)到由在相应数据字段集合s中的相应维度指定的细节级别。在一些实现方式中,将度量m的值上卷到由在相应数据字段集合s中的相应维度指定的细节级别包括(1828)根据在相应数据字段集合s中的相应维度来将包含度量m的数据表的行划分成组,并为每个组计算单个聚合值。通常,计算单个聚合的运算符是(1830)以下中的一个:sum、count、min、max、或average。在一些实现方式中,使用关键字cnt和avg来代替count和average。一些实现方式提供额外的聚合运算符。例如,一些实现方式提供attr()聚合运算符。对于每个组,attr()运算符确定在组中的所有值是否相同。如果是这样,attr()运算符返回该组的唯一值;否则,attr()运算符返回“*”,指示对于该组有多个值。在一些实现方式中,单个聚合运算符是(1830)以下中的一个:sum、count、countd、min、max、avg、median、attr、percentile、stdev、stdevp、var、和varp。对于每个(1824)数据字段集合s294,该过程还根据在相应数据字段集合s294中的数据字段以及根据在s中的每个数据字段所关联到的相应视觉变量282来建立(1832)相应数据可视化。在一些实现方式中,建立相应数据可视化包括(1834)使用从视觉规范104生成的一个或更多个数据库查询从一个或更多个数据源106中检索数据的元组。在一些实现方式中,这些元组包括(1836)根据在数据字段集合s294中的相应维度聚合的数据。在一些实现方式中,该过程在计算设备200的图形用户界面102中显示(1838)相应数据可视化。在一些实现方式中,显示数据可视化包括(1840)生成多个视觉标记,每个标记对应于从一个或更多个数据源中检索的相应元组。在一些实现方式中,图形用户界面102包括数据可视化区域412,并且数据可视化被显示在数据可视化区域中。一些数据可视化应用采用数据可视化所需的字段(“viz”),其可以在数据可视化用户界面102中被指定,并从包含这些元素的数据源中提取平面的、非标准化表(denormalizedtable)。通过扁平化成(flattenout)数据,数据模型可以复制基础数据源(underlyingdatasource)中的一些单独表中的数据。当聚合函数在此数据模型上运行时,这些度量的聚合可能会受到这些副本的影响,从而产生令人惊讶的(即,意外和/或不希望的)结果。平面模型(flatmodel)的另一个问题是,它引入了可能的低效率。在许多情况下,用户可以使用lod计算来获得预期的计算结果,它覆盖整个平面结果表以进行正确的聚合。因为表是平面的,所以即使相关字段在单个小的子表中,过滤也发生在整个结果表中。公开的实现方式解决了这些和其他问题。对象模型中的对象是可以通过主键引用的数据的集合。它们可能是sql表、电子表格区域或sql存储过程。还可以创建合成对象来合并对象模型或解析数据关系中的歧义。每个对象都可以在对象模型中通过其列的列表来表征:哪些列构成主键,以及哪些列用作外键。在一些情况下,只有字段的子集可以用作viz中的维度。数据系统的对象模型是一个图形,该图形将从外键到主键的多对一关系中的各种对象联系起来。边缘从多(外键)侧指向一(主键)侧。重要的是,对象模型图形是单连接的,并且不包含循环,以使得通过图形的路径是明确的。这个图形的整体形状是一棵多树(polytree)。对象模型引擎从对象模型的角度创建aql模型,并从viz创建抽象查询。处理viz的查询使用对象模型中的角度(perspective)。角度是viz的子树,并且它定义了可以在viz中用作维度的字段(子树上的那些字段)的集合。当对象模型引擎检查viz中的字段时,它将字段分成聚合值(“度量”),以及确定viz的细节级别的其他值(“维度”)。图19a和图19b提供了受支持的对象模型图形的两个示例。框中的“m”指示对应于该框的对象具有一个或更多个度量。框中的“d”指示对应于该框的对象具有一个或更多个维度。查看受支持的模型,包含维度的对象有根节点。例如,图19a中的根节点是节点1902。在图19b中,根节点是节点1912。请注意,在根节点之前,图19b中还有其他节点,但是它们没有维度。利用这种结构,所有具有维度的节点都可以通过一系列外键到主键的关系从根节点到达(如图19a和图19b中的箭头所示)。图19c类似于图19b,但是具有从根节点1922不可到达的附加节点1924。在一些实现方式中,在存在不可以从根到达的节点(例如节点1924)的情况下,在不可到达的节点处的所有字段被视为度量或属性。图19d示出了另一个有问题的情况,其中在两个节点之间有两条不同的路径1936和1938。一些实现方式不支持这种情况,因为它需要任意选择一条路径,从而导致不可预测的结果。给定字段的集合和对该集合有效的角度,对象模型查询处理器修改aql模型中的数据查询。然后,查询管线进一步处理该模型,并进一步优化数据查询以提高效率。对象模型引擎遵循这些步骤。步骤1.从集合中识别维度字段。使用这些维度的“选择不同(selectdistinct)”查询定义了对象模型查询结果的细节级别。在包含这些维度字段的对象模型中找到最小子树,并识别该子树的根。(如果没有子树,则这不是字段的有效角度。)维度查询树是包含所有维度的子树。接下来,形成子查询,该子查询通过维度查询树select这些维度。因为这使用了innerjoin,所以该域将仅是每个维度都具有非空值(non-nullvalue)的那些行。一些实现方式使用union来引入具有空列的行。最后,应用维度过滤器(如果有的话)。步骤2.对于每个聚合度量,将度量对象的主键添加到步骤1中识别的维度中。找到这些字段的最小子树,如步骤1所示。对于只包含标量字段的计算,以同样的方式处理这些字段。对于仅使用聚合字段的计算,将这些字段视为聚合度量(应用于聚合度量的最终聚合除外)。针对这些字段和(非聚合的)度量本身执行不同的子查询。这给出了结果集,在该结果集中每个度量记录都在整体查询的细节级别(lod)处被复制/拷贝/包括。评估计算,将结果视为查询的其余部分的另一个聚合度量。接下来,从查询中移除度量对象的主键,并创建子查询,通过度量的聚合函数进行聚合,按剩余维度进行分组。这给出了结果集,该结果集具有由维度和另一个具有明确地聚合到这些维度的lod的度量的字段组成的键。仅使用聚合字段来评估计算结果。这些评估将导致关于查询的其余部分的新的聚合度量字段。步骤3.在维度上将度量子查询join在一起。当域查询包括空事实(emptyfact)时,这些join可以是部分outerjoin,以保留来自步骤1的域。最后,对该查询的结果应用度量过滤器。这种方法定义了查询,其中结果集具有以下属性:·维度的集合构成结果集的多列键。该集合定义结果的域,并确立哪些行将在结果集中。·每个聚合度量是单独聚合的(精确到域的细节级别)。向左移动的度量被复制到lod。向右移动的度量被聚合。过滤器和计算成为产生的aql模型中的人工物(artifact)。通常,它们将与定义效果的正确细节级别的对象一起放置在树中。对象模型查询过程不更改计算或过滤器的执行顺序。这是由aql执行管线处理的。雪花和树是对象模型的常见示例。在对象模型中,对象是基本的构建块。要成为对象,数据源上的子查询如下:·相对于查询中的度量被标准化。每行表示在viz中用作度量的所有字段的不同度量。请注意,维度字段的标准化化不是必需的。·如果对象位于对象模型树的根,则没有外键可以引用它。在这些情况下,出于此查询过程的目的,对象可能不需要具有主键。创作(author)对象模型的基本任务是将数据源中的对象(沿维度)连接到(可能是多个树当中的)一个树中,其中边缘是对象之间的多对一关系。树状关联图(joingraph)确保了查询将是明确的。多对一关系确保关联树的节点对象中将不会有度量重复。雪花是树的一种特殊情况,其中所有的度量都在根对象中。这些在对象模型中特别容易转换,因为对于聚合函数不需要进行特别注意。对象模型不更改对这些数据集的查询语义,但它通常更有效。图20a-图20f提供了可用于跟踪销售的雪花示例。图20a示出了相关的数据库表行项目(lineitems)2002、产品2004、订单2006和客户2004。如果数据分析师创建了viz按产品类别和订单邮政编码来计算总价格,则该过程将来自行项目2002、产品2004和订单2006表的信息关联起来。如图20b所示,用户已经将数据字段类别2020和邮政编码2022放在行工具架上,并且sum(价格)2024被指定为文本字段。这创建文本表2026,并且使用如图20c所示的查询。尽管图20c中的查询是准确和高效的,但是应用对象模型转换是有益的。对象模型引擎的步骤1隔离了将用于索引查询结果的键,如图20d所示。这将为产品类别和订单邮政编码的每个唯一组合创建不同的行。如图20e所示,该过程的步骤2针对键聚合度量(价格)。这为类别和邮政编码的每个不同组合计算了不同的值sum(lineitems.price)。最后,在步骤3中,对象模型引擎将两个结果关联在一起,如图20f中的查询所示。这个新查询不会更改查询的语义。在一些情况下,这个新的查询允许更有效的过滤和处理“显示空字段”的情况。查询管线可以将该查询优化为类似于类查询(classquery)或更好的查询,特别是因为它具有对象模型信息。图21a-图21i将前面的示例扩展到不是雪花的树。如图21a所示,该模式现在在订单表2006中包含销售税(salestax)21110。请注意,这是销售税2110的逻辑位置,因为每个订单都会计算一次销售税。如图21b所示,用户已经将两个度量值sum(价格)2126和sum(销售税)2128放入度量值中,并且度量值2124已经被分配给文本编码。此外,用户已将数据字段订单2122放在行工具架上,并且将度量名称字段2120放在列工具架上。如图21d所示,在使用典型查询创建的数据可视化中查看行2132和2134的数据是有用的。尽管总价是正确的,但销售税金额被夸大了。查询的数据如图21c所示。因为它在订单层面合计了价格字段和销售税字段,所以每当有一个以上的行项目时,销售税就会在每个订单上被重复。了解对象模型引擎的步骤如何解决这个问题是很有用的。对象模型引擎的步骤1使用图21e所示的简单查询,为每个order.id提供单独的行。因为有两个度量,所以在步骤2中有查询。检索价格信息使用图21f中的查询,而销售税信息使用图21g中的查询。在这两种情况下,它们都可以在适当的lod处(即按order.id)正确计算聚合值。步骤3将这三个子查询关联在一起,恰当地为这两个度量获得不同的细节级别,如图21h所示。请注意,这使用了部分外部关联(outerjoin)来保存viz中的所有订单,即使是那些没有行项目的那些订单也是如此。图22a-图22i示出了在树的不同分支中具有度量和维度,并展示了对由对象模型引擎提供的更复杂的实现方式的需求。图22a示出了电影和演员的数据库模式的一小部分以及它们之间的关系(包括演员表2206、电影表2204和出演(appearances)表2202)。请注意,演员和电影之间的关系是多对多。此外,单个演员可以在单部电影中以多个角色出演。出演表2202因此用于说明电影2204和演员2206之间的复杂关系。这些表的简单关联产生如图22b所示的结果集。(实际美元金额已被较小的整数所取代,以简化呈现)。从这个简单的电影和演员数据库中,人们可以使用图22c所示的viz询问演员出演的电影有多少票房(grossed)。这里,用户已经将数据字段全名(fullname)2222放置在行工具架上,并将数据字段sum(票房)2224放置在文本编码图标上。请注意,每个演员都有一些重复计数,如图2226所示:petersellers实际上只出演了两部电影,总票房为2000美元,而johnrhys-davies出演了三部电影,总票房为3000美元。这些不正确的结果是由典型的查询生成的,如图22d所示。另一方面,利用对象模型,过程以通常的方式进行。对象模型过程的步骤1生成了不同演员的列表,如图22e所示。在步骤2中,该过程首先在由演员的全名和movie.id定义的细节级别(比viz的细节级别更精细)处确定票房。这在图22f中被示出。接下来,如图22g所示,在viz的lod处聚合中间表。最后,步骤3如预期的那样组合两个查询,这次使用了innerjoin来只获取已经在电影中的演员。组合结果的查询在图22h中示出。所产生的可视化在图22i中示出。如这里所见,可视化2236具有正确的数据。viz中的计算的字段可以类似于其他字段进行处理,即使用于计算的源数据并不都是从单个对象中提取的。当计算基于单个对象时,它们在适当的细节级别处收集并在该级别处计算,然后以通常的方式聚合起来。当计算使用来自不同对象的字段时,有两种情况:·被视为标量的非聚合字段被复制/拷贝/包括到单个lod中。如果可能的话,对象模型引擎在包含它们的子树的根处为所有这些标量建立lod。·在viz的lod处聚合计算中的聚合函数,就像关于度量的聚合函数一样。考虑简单的行项目/订单模型,如图23所示。扩展=[价格]*[数量](extension=[price]*[quantity])的计算是在行项目表的lod处计算的。它的作用就像该表上的另一个可用字段。现在,如果每个客户都有可应用于其购买的折扣率,则计算如下:折扣扩展=([价格]*[数量])*(1-[折扣率])(discountedextension=([price]*[quantity])*(1-[discountrate]))在行项目表的lod处也有意义。一般来说,未聚合的字段被收集到包含它们的子树的根,以便进行计算。这样,即使例如行项目利润=(([价格]*(1-[折扣率)]-[库存价格])*[数量](lineitemprofit=(([price]*(1-[discountrate])-[stockingprice])*[quantity])这样复杂的计算,也是在行项目的lod处计算的,其是“正确的”。请注意,一些不能通过对象模型中的子树连接的简单计算在对象模型引擎中没有意义。例如,考虑净销售额=[退款.金额]-[折扣扩展](netsales=[refunds.amount]-[discountedextension])。在这种计算有用的情况下没有lod。计算通常在viz定义内聚合。在这些情况下,对象模型将它们视为它们公共子树根的lod处的度量,并根据vizlod聚合它们。聚合计算(计算中的所有度量都被聚合)也是在viz的lod处计算的。考虑两种计算:扩展=[价格]*[数量]以及扩展总和=sum([扩展])(sumofextension=sum([extension]))。两个度量球粒,sum(扩展)和aggr(扩展总和),在任何特定的viz给出相同的结果。对于组合聚合和标量的计算,对象模型引擎分步地处理它们。首先,标量被收集到适当的lod,然后聚合被聚合到同一lod。计算可以在该lod处执行。viz中的任何其他聚合都是在这一点上完成的。例如,在表达式折扣扩展=sum([价格]*[数量])*(1-[折扣率])中,[折扣扩展]是在[折扣率]的lod处计算的,该lod在订单对象中。许多计算都涉及if-then语句,例如涉及参数的该计算:参数不属于任何对象,并且对于任何lod都是常数。该计算将在lineitem对象处具有lod。if-then-else语句的两个分支必须具有相同的lod,使得可以独立于特定的数据来分析该计算。因为对象模型通常由innerjoin组成,所以可以在对象级别处应用过滤器(直接在该对象的子查询中应用)。这导致了高效的查询,与以前的模型相比没有语义更改。一些实施方式在每个对象级别(per-objectlevel)上给用户一个“显示所有记录(showallrecords)”的选择。这对在查询的第一部分中建立的维度的域有影响。最初,维度查询被指定为好像使用innerjoin,这不允许具有缺少链接的行。一种解决方案是使用left和rightjoin的组合。考虑图20a所示的模式。假设用户请求显示客户对象的所有记录。一些实现方式使用union将额外的客户添加到初始维度域查询中。这些实现方式然后将其rightjoin到订单中,并且然后rightjoin到行项目中,以开始创建包括所有客户的域。在一些实施方式中,查询被分成子查询以避免歧义。如果客户对象与任何其他对象有多对一的关系,角度的每个部分都在子查询中被捕获,则可以创建另一个子查询来将客户对象leftjoin到这些对象。然后应用直到维度域的lod的rightjoin子查询的嵌套。每一个另外的子树都被收集到它自己的子查询中(从原始主干(spine)到新的子查询的rightjoin)。这提供了明确的整体查询,这将所有维度从客户对象提升到查询的域。可替代的组合方法经由fullouterjoin对在每个子查询中具有显示所有对象的子查询使用join。对象模型引擎提高了获得正确聚合计算的能力,而不会出现度量数据的虚假重复。这是通过使用数据的样子(shape)(包括表之间的多对一关系)以语义正确的方式控制复制和重复数据消除来实现的。由对象模型引擎创建的查询被分解成多个组成部分,这些组成部分首先将必要的数据复制到单个表中,然后在度量聚合之前对其进行重复数据消除(即,移除虚假的重复)。图24a示出了示例数据源的样子。该数据源跟踪在电影2406中扮演角色2404的演员2408。这些数据段都由出演2402连接,出演2402是特定演员在特定电影中扮演特定角色的实例。这个数据源中有很多复制的机会,因为演员在很多电影里扮演,并且电影有很多演员。此外,同一个演员可以在单部电影中扮演一个以上角色。将这四个表关联在一起将产生一组平面(flat)行,如图24b所示。假设用户想要创建一个viz,其显示每个导演合作过多少演员。请注意,单个演员可能与每个导演都有多个角色和/或电影。请看导演peterjackson,我们应该看到他已经指导了四部电影中的四名演员(在这个有限的样本内)。然而,图24c示出有十行2420,其中peterjackson与一个演员配对。图24d中的数据可视化示出了对应于10个演员的条(bar)2422,这被夸大了。在这种可视化中,电影之间(例如,peterjackson电影中的livtyler)和电影内部(例如,johnrhys-davies饰演gimli和treebeard)都有重复。基于扁平化表(flattenedtable)的查询多次计数了同一数据。图24e示出了对同一数据源使用对象模型引擎来计算正确的结果。对于对象模型查询,演员对象2408的主键2428被添加到导演和演员.全名(actors.fullname)的selection来创建初始导演/演员结果2430。这在重复数据消除步骤中被使用。注意:大多数对象(除了对象模型树根处的对象之外的所有对象)都有主键。这是保证在对象中唯一的字段(或组合在一起的字段的集合)。主键充当对象中每一行的索引。接下来,按维度(导演)和度量的主键(actors.id)进行分组(2440)去除了重复,以产生重复数据消除的导演/演员结果集2432。每个(导演、演员)对在这个中间表2432中只出现一次。度量对象的主键保证是唯一的,因此在分组中使用它会产生正确的结果(例如,即使有多个具有相同姓名的演员)。在这个示例中,没有任何演员的重复全名,但真实的数据集可能会重复。最后,数据按导演聚合(2442)以在聚合的结果集2434中获得每个导演的演员计数。聚合的结果集用于构建(2444)数据可视化2436,其包括具有适当计数的peterjackson的条2438。图25a-图25c示出了使用对象模型引擎来产生正确的细节级别(lod)计算。假设用户想看电影的总“明星魅力(starpower)”。在这个示例中,每个演员的“明星魅力”被近似为每个演员电影获得的票房收入。那么电影的明星魅力就是电影中所有演员的明星魅力之和。该示例使用如图24a所示的数据源。用户可以利用lod计算将每个演员的明星魅力计算为:明星魅力={fixed[演员.全名]:sum([票房])}(starpower={fixed[actor.fullname]:sum([gross])})。然而,为了避免重复,这个lod计算应该经由对象模型语义来计算。如图25a所示,第一步骤是关联电影表2406、出演表2402和演员表2408,以创建第一结果集2502。该第一结果集2502具有演员johnrhys-davies的多个行2520(包括同一电影的多个行)。接下来,对象模型引擎对来自第一结果集2502的行进行重复数据消除(2515),以创建第二结果集2504。在第二结果集2504中,演员johnrhys-davies只有三行2522。在第二结果集2504中,演员仅与电影配对一次。最后,对象模型引擎聚合(2512)来自按演员的第二结果集的数据,以计算第三结果集2506中每个演员的sum(票房)(“明星魅力”)。该lod计算有效地创建了新的对象,该新的对象具有目标lod的主键(例如,全名)和聚合的度量(例如,sum(票房))。图25b示出了将明星魅力结果集2506与关联电影和演员的表2532关联(2536)。这为电影创建了明星魅力的结果集2534,但有一些重复的行。在图25c中,对象模型引擎对中间结果集2534进行重复数据消除(2550),以形成重复数据消除的结果集2540。最后,对象模型引擎聚合(2552)重复数据消除的结果集,以计算最终结果集2542中每部电影的总明星魅力。图26a-图26d示出了对象模型引擎如何准确地处理向viz添加过滤器并使用图24a所示的数据对象模型。假设用户想要查看每个演员的电影获得的总票房收入,但是只查看演员扮演非人类角色的电影。这有可能造成重复问题。例如,图26a示出了基于扁平化数据集2602创建的数据可视化2604。使用这种扁平化数据集,一些总和被夸大了。例如,johnrhys-davies和livtyler都在同一部《指环王(lordoftherings)》电影中,但由于johnrhys-davies扮演了多个非人类,所以他的数量更大。这由数据可视化2604中的条2606和条2608示出。在图26b中,每个(演员、电影)组合的票房数据2610被关联(2620)以过滤数据2612,从而创建过滤的但重复的结果集2614。对象模型引擎构建关于度量“票房”的票房数据结果集,其包括维度(actors.fullname)、度量(movies.gross)、以及度量对象的主键(movies.id)。过滤器可以被认为是它自己的查询。它使用度量查询将使用的相同的列(即viz维度加上度量的主键,它们是actors.fullname和movies.id)。但是,对象模型引擎添加了过滤器计算(以及需要被计算的所有字段),而不是度量列。在这里,过滤器计算是物种<>“人类”(species<>“human”),其对于精灵、树人、矮人和神灵返回真(true)。适当的字段被添加到复制查询和过滤器中,它们可以逐行关联。对象模型引擎还可以对过滤器=真(filter=true)进行join,去除关于人类角色的行。但是,请注意,johnrhys-davies仍有一些重复。在图26b中的最终结果集2614中注意到的重复可以通过应用groupby与join来去除,如图26c所示。在图26c中,join groupby操作2622产生没有重复的最终结果集2624。groupby已移除了重复项。三部《指环王》电影对于livtyler和johnrhys-davies都各自只计数一次。(seanbean在《护戒使者(thefellowshipofthering)》中的出演已被groupby之前的过滤器移除)。现在可以正确计算聚合。在图26d中,来自图26c的最终结果集2624被聚合(2640)以形成结果集2632,其在数据可视化2634中被使用(2642)。请注意,如他们应该的那样,johnrhys-davies和livtyler的条2636和条2638具有相同的大小。图27a-图27i提供了使用对象模型引擎以应用过滤器的附加示例。考虑数据源过滤器,该数据源过滤器可能位于不在数据服务器公开(expose)的元数据中的对象或字段上。例如,假设角色是“隐藏的”对象,而物种<>“人类”是隐藏的数据源过滤器。客户的viz请求按演员姓名的票房。客户不知道对于物种<>“人类”的过滤器。如果没有应用过滤器,则结果将如图27a所示。但这显然包括以“人类”身份出现的演员的出演。请注意,viz中显式地提到的两个对象是演员和电影。我们还需要考虑将它们关联在一起的对象,其是出演。在图27b中,对象模型引擎在重复的非人类角色表2710和角色过滤器表2712之间执行join2720,以形成被过滤的但具有重复数据的中间结果集2714。在图27b中,执行了相同的操作,但是使用了join与groupby操作2722,以便形成被过滤的和重复数据消除的中间结果集2716。图27d示出了通过将角色过滤器表2712join2740到电影结果集2732来将过滤器应用到电影结果集2732。这产生被过滤但具有重复数据的电影中间结果集。与演员查询一样,可以通过应用join与groupby2750来去除重复,如图27e所示。这产生了被过滤和重复数据消除的中间电影结果集2752。图27f示出了将join2760应用于演员中间结果集2716和电影中间结果集2752,这产生了被过滤的最终结果集2762。然而,这种技术产生了额外的行2764。将演员和电影的查询分开,导致错误包括了seanbean在《护戒使者》中的出演。他扮演了非人类(宙斯),而《护戒使者》中的确有非人类,但他在《护戒使者》中是以人类boromir的身份出演。图27g-图27i示出了对象模型引擎用来解决这个问题的可替代的过程。在图27g中,对象模型引擎在角色过滤器表2712和初始表2710之间执行join与groupby2770,初始表2710具有由每个演员扮演的角色。这产生了中间结果集2772,该中间结果集2772被过滤并且具有由每个演员扮演的角色。在图27h中,对象模型引擎在角色过滤器2712和将票房与电影角色相关联的表2732之间执行join与groupby2780。这产生了被过滤的中间结果集2782,并且将票房与电影角色相关联。最后,在图27i中,对象模型引擎在被过滤的演员和(根据所扮演的角色)被过滤的电影之间应用join,以产生最终的正确结果集2792。请注意,这个结果集不包括图27f的表2762中看到的无关行(extraneousrow)2764。这里,两个表之间的join不仅包括出演中的信息,还包括关于它们自己的角色列的信息。这在最终结果中去除了boromir。强制过滤器总是作为viz的内部关联被应用,而可选过滤器在它们适用于viz时被应用(例如,当过滤器与viz的字段在对象模型的同一子树“中(in)”时)。在一些实现方式中,对象模型引擎获取viz的维度和度量,在对象模型中找到它们的最小公共祖先(ancestor),并在过滤器中找到所有字段的最小公共祖先。如果这些对象中的一个是另一个的直接祖先,则过滤器适用于viz。例如,考虑过滤器物种<>“人类”,这是可选的。在按导演计算的演员的计数时,关于物种<>“人类”的过滤器是适用的。另一方面,在按导演计算票房的总和时,关于物种<>“人类”的过滤器不适用。当有多个度量时,就存在是否应该协调它们的问题。一些实现方式选择单一的解决方案,而其他实现方式为用户提供可配置的选项。例如,·物种过滤器将移除导演/演员组合中演员扮演人类的行。·对于导演/票房组合,是否应移除相同的行?·如果是,那么viz的票房部分看起来将不同于它在独立viz中看起来的那样。·如果不是,那么票房部分和演员部分将考虑不同的电影,并且将可能有不同的域。这些问题在图28a-图28c中示出。在图28a中,第一表2802具有聚合的数据,并且没有应用过滤器。如果应用了(2810)过滤器,则结果集2804仅具有单行,并且来自该单行的数据与第一结果集中的对应行不匹配。类似地,在图28b中,未过滤的第一结果集2812具有六行。如果数据被过滤(2820),则结果集2814只有单行,并且计数不同于第一结果集。图28c示出了对不同地应用过滤器的两个结果集2832和2834进行比较。在第一结果集2832中,按度量应用过滤器,而在第二结果集2834中,在所有字段上应用过滤器。在本发明的描述中使用的术语仅为了描述特定实现方式的目的,且并不意欲限制本发明。如在本发明的描述和所附的权利要求中所使用的,单数形式“一个(a)”、“一个(an)”、和“所述(the)”意欲也包括复数形式,除非上下文另外清楚地指示。还要理解的是,如在本文使用的术语“和/或”指相关的所列出的项目中的一个或更多个的任何和所有可能的组合并包括这些组合。还要理解的是,术语“包括(comprises)”和/或“包括(comprising)”当在本说明书中使用时指定所陈述的特征、步骤、操作、元件、和/或部件的存在,但不排除一个或更多个其它特征、步骤、操作、元件、部件、和/或它们的组合的存在或添加。为了解释的目的,前面的描述参考了特定的实现方式进行描述。然而,上面的说明性讨论并没有被规定为无遗漏的或将本发明限制到所公开的精确形式。鉴于上面的教导,许多修改和变形是可能的。实现方式被选择和描述是为了最好地解释本发明的原理及其实际应用,以从而使本领域中的技术人员能够以适合于所设想的特定用途的各种修改最好地利用本发明和各种实现方式。当前第1页12当前第1页12
转载请注明原文地址:https://doc.8miu.com/read-350189.html