数据分析器:HTML 表格转图表






4.91/5 (23投票s)
几行代码即可根据带有筛选选项的 HTML 表格内容创建动态图表
引言
“数据分析器”,顾名思义,可以分析 HTML 表格形式的数据,并提供所有可能的组合选项来将这些值显示为图表(柱状图/饼图)。
背景
无论是石器时代还是超级计算机时代,“百闻不如一见”这句名言在传递信息方面始终被证明是正确的。
基于我在开发和设计领域的经验,我注意到大多数网站/Web 应用程序都以报告的形式生成 HTML 表格内容。这些报告可以使用市场上任何可用的工具/技术生成。其中,能够同时提供图表和报告显示选项的网站/应用程序将非常少。即使他们提供了,用户对报告内容的交互也受到很大限制,无法动态更改图表。
因此,在这里,我为您提供一个完整的基于 JavaScript 的解决方案,您只需添加几行代码即可将您的 HTML 表格内容与您选择的图表集成。
听起来不错?让我们开始吧……
想象一下,您有如下所示的 HTML 表格内容(见下图 1)

为用户提供某些功能的详细报告固然好,但搜索/过滤功能呢?您可能需要在后端/前端工具中编写一些额外的逻辑来实现它。
为了便于理解,我在表格中添加了一个操作按钮(Analyze),如下所示(见下图 2)

没有必要添加任何按钮,您可以在页面加载时直接调用脚本。现在,当您单击此操作按钮时,一些神奇的事情就会发生,您会看到一些新添加的下拉框,以及记录总数和多个图表选项,如下所示(见下图 3)

在这里,您可以看到表格中的所有列都已自动添加到筛选条件中,此外还有一个“全局搜索”选项,可以对表格的所有文本内容进行搜索。使用此筛选实用程序,用户可以全局搜索或针对任何特定列进行搜索。例如,我想搜索名为 *'Alex'* 的内容。下图 4 显示表格内容已自动过滤,仅显示包含内容 - *'Alex'* 的记录。记录总数也已更新。

在图 3 中,您可能已经注意到在操作按钮(Analyze)的底部添加了一些额外的下拉框。它们是
- 图表类型:指示您想看到的图表类型。可能的值是- 条形图
- 饼图
- 随机(以上任何一种图表类型都可以随机选择)
 
- 可用图表:基于执行的分析,此下拉框提供了数据中所有可用图表的列表。根据逻辑,这些图表始终基于 HTML 表头列。而且,它是动态填充的。
- 组合(操作):[可选] 这是 2.0 版本的一个附加功能。它表示您在生成图表时希望执行什么数学运算。目前可能的值是- Sum
- Average
 
- 的(数字列):[可选] 这是 2.0 版本的一个附加功能。它表示您希望在哪个数字列上执行上述操作。
所有这些值组合在一起,为您提供图表结果。
从数据分析器 2.0 版本开始,我删除了 JSChart 库。因此,图表库的选择已删除。默认情况下,输出将使用 Open flash chart (OFC) v1.0 (http://teethgrinder.co.uk/open-flash-chart/) 渲染。
选择“可用图表”下拉框中的任何选项后,您将看到如下所示的图表(见下图 5)

到目前为止,大多数人可能会认为重复开发已经免费提供的功能是浪费精力。接下来是关键一步。
选择操作和列表中的任何数字列(如上图 3 所示)。当这些信息与所选图表结合时,结果将如下所示(见下图 6)

虽然图 5 显示了按供应商名称分组的记录总数,但图 6 显示了供应商所产生的服务费用的汇总。这难道不令人兴奋吗?
您在图 4 中看到了过滤实用程序,对吧?那么,过滤数据后,如何绘制基于过滤记录的新图表呢?这是解决方案。在此演示中,在执行过滤操作后,再次单击 Analyze 操作按钮。哈!您的图表已准备就绪。根据表格内容的更改,“可用图表”下拉框将以新内容刷新,如下所示(见下图 7)

相关的图表显示在下图 8 中

让我们对这些过滤后的数据执行一些操作。图 9 显示了市民 Alex 为她提供的服务支付的平均服务费用。

添加更多复杂性? 让我们执行多个过滤条件。结果将如下所示(见下图 10)

让我们看看“随机”图表类型是什么样的?当您从“可用图表”下拉框中选择“显示所有图表”选项时会发生什么?结果将是基于所选操作的所有图表的随机显示,如下所示(见下图 11)

如何处理错误?如果找不到记录怎么办? well,代码中已处理所有情况。如果没有可用记录,或者所有可用记录都是唯一的,因此无法生成图表,您将看到相应的消息。请看下图 12

好了,以上就是数据分析器的所有功能。希望您觉得它很有趣。如果是,请继续阅读以了解如何将其集成到您的代码中。
下一步:集成步骤
首先,需要执行以下步骤才能将数据分析器集成到您当前的 HTML 代码中。
- 在您的 HTML 页面的 HEAD部分包含以下 CSS 和 JS 文件<link rel="stylesheet" type="text/css" href="dataanalyzer.css" /> <script language="JavaScript" src="DataAnalyzer.js"></script> 
- 包含以下 Open Flash Chart 的脚本。添加/替换为您自己的图表脚本(但您可能需要相应地修改数据分析器的代码)。<script language="JavaScript" src="swfobject.js"></script> 
- 创建两个 DIV占位符用于显示图表和错误消息<div id="AnalysisStatus"></div> <div id="chartContainer"></div> 
- 创建 DataAnalyzer对象并传递所需的参数<script language="JavaScript"> var analyzer = new DataAnalyzer('analyzer', 'InvoiceTable', 1, true); function doAnalyze() { analyzer.start(); } // invoke function doAnalyze() on-load or on user event (button or link click). </script>
这样就可以了。我们可以开始工作了!!!
理解 API
好吧,如果您一直觉得这很有趣,那么对数据分析器中使用的 API 有一个清晰的理解将是很棒的。
正如您可能注意到的,数据分析器对象就像其他 JavaScript 对象一样创建。语法是
var analyzer = new DataAnalyzer
(thisObject, dataSourceId, vHeaderStartsAt, vAddFilter, vBypassCols, vAnalyzeCols);   
参数含义
- thisObject:[必需] 自我引用的对象名称。它将是数据分析器对象的变量名。
- dataSourceId:[必需] 要引用和分析的 HTML 表格的 ID。
- vHeaderStartsAt:[可选] HTML 表格标题行的行索引。默认为- 1。
- vAddFilter:[可选] 决定您是否要包含筛选选项的标志。默认为- false。
- vBypassCols:[可选] 列索引或“命名”列(即,标题列的名称 AS-IS)或两者的混合。此数组中列出的列**既不**会被考虑用于筛选条件,也不会被考虑用于“可用图表”选项。如果为参数- vAnalyzeCols提供了值,此参数值优先级较低。
- vAnalyzeCols:[可选] 列索引或“命名”列(即,标题列的名称 AS-IS)或两者的混合。此数组中列出的列**仅**会被考虑用于筛选条件。但对于“可用图表”选项,它们可能会或可能不会包含,具体取决于分析。此参数值比之前的- vBypassCols参数值优先级更高。如果提供,将忽略- vBypassCols的值。添加此参数作为最后一个参数的原因是,分析所需的参数比需要绕过的参数多。
API 列表中的下一个是数据分析器支持的 public 方法集。它们是
(A) start 方法
这是开发人员需要处理/调用的第一个(也是唯一一个)方法。如果开发人员在其之上编写了任何自定义代码,则其余方法仅需手动调用。语法是
analyzer.start(vFilterOnly, vAutoAnalyzeOnFilter); 
参数含义
- vFilterOnly:[可选] 默认值为- false。如果设置为- true,并且构造函数中的- vAddFilter参数也设置为- true,则将禁用图表选项。只有 HTML 表格内容过滤选项可用。如果- vAddFilter参数为- false,则此参数的任何值均无关紧要。
- vAutoAnalyzeOnFilter:[可选] 默认值为- false。如果设置为- true,将自动分析 HTML 表格内容并填充相关的“可用图表”下拉框。设置为- false时,开发人员需要根据用户事件(按钮单击等)调用- analyzer.start()方法。如果- vFilterOnly参数为- true,则此参数的任何值均无关紧要。
下表显示了使用这些参数的各种组合的可能结果
| vAddFilter | vFilterOnly | vAutoAnalyzeOnFilter | 可能的结果 | 
| false(或null) | 不适用 | 不适用 | 将仅显示图表 | 
| true | true | 不适用 | 将仅显示过滤器 | 
| true | false | false | 用户需要触发某个事件来在过滤后分析和生成图表 | 
| true | false | true | 过滤后将自动分析表内容 | 
(B) filterTable 方法
此方法通常会自动绑定到基于上面定义的 vAddFilter 参数创建的搜索文本框。无需显式调用此方法。语法是
analyzer.filterTable(phrase, tableId, searchIn, headerStartsAt);
参数含义
- phrase:[可选] 用于搜索 HTML 表格内容的过滤短语。如果留空,所有记录将按原样显示。
- tableId:[必需] 将被搜索的源表的 ID。
- searchIn:[可选] 要在其中查找过滤短语的表格的列索引。如果留空,将在所有列中搜索提供的短语。
- headerStartsAt:[可选] 数值字段,用于确定表内容从何处开始。默认为 1。
(C) draw 方法
此方法通常会自动绑定到“可用图表”下拉框。无需显式调用此方法。需要集成自定义图表库的开发人员可能需要查看此方法的代码以根据需要进行修改。语法是
analyzer.draw(reportIndex);
参数含义
- reportIndex:[必需] 要在屏幕上绘制的图表的索引。可以是单个图表索引或所有可用图表。
自定义
如果您喜欢这种显示表格报告并从中生成图表的概念,我相信您会考虑根据您的应用程序/网站进行自定义。以下是一些您需要进行更改以适应您需求的地方
- 根据需要修改 dataanalyzer.css。
- 包含您的自定义图表库 JavaScript 文件
- 在 DataAnalyzer.js 文件中,可以进行以下更改- 修改 private方法 -addAutoFilter()以更改文本、对齐方式、格式等。
- 修改 private方法 -report()以更改图表配置 - 图表类型、文本、对齐方式、格式等。
- 修改 public方法 -draw()以实现自定义图表及相关格式
- 修改 public方法 -filterTable()以自定义交替行颜色、文本等的样式
 
- 修改 
浏览器兼容性
此代码与所有主要浏览器兼容 - Internet Explorer、Chrome、Firefox、Safari 等。
幕后:算法
这一部分是为那些热爱算法并希望深入了解解决方案/工具实际逻辑实现的人准备的。以下是我设计此数据分析器所遵循的步骤。
- analyzer.start()方法内部调用- private方法 -- init()
- init()方法将进行验证- 传递的参数
- HTML 表格是否包含足够的行来渲染图表
- 要分析或绕过的特定列
 
- 接下来,analyzer.start()方法将调用private方法 -analyze()。
- 实际数据分析在此方法中处理。它又分为四个子例程- 分析表头
		- 这是使用 private方法 -analyzeHeaders()完成的。它将解析标题行(根据构造函数参数中提供的索引)。此解析将为每一列准备一个 METADATA。
- Metadata 属性是 - columnRow、columnIndex、columnLabel、columnType(初始未知或null)和columnData(初始为空)
- 没有文本内容的标题列(这些列可能用于格式化和间距)将没有元数据。
- 如果 passed vAnalyzeCols参数,元数据将仅包含与此数组中的值匹配的标题列。
- 如果 passed vBypassCols参数,与此数组中的值匹配的标题列将不会包含在元数据中。
- 最后,它将检查标志 - vAddFilter。如果为true,则将调用另一个private方法 -addAutoFilter()。- addAutoFilter()方法会遍历元数据,并创建将放置在 HTML 表格上方的动态 HTML 代码。这就是自动搜索/过滤功能是如何添加的。
- 当搜索特定文本时,所有不包含搜索文本的行都将被隐藏。清除搜索文本后,这些隐藏的行将再次可见。
 
 
- 这是使用 
- 分析表内容
		- 这是使用 private方法 -analyzeData()完成的。它遍历每一行可见列及其中的每个单元格。
- 只有当 vAddFilter或vFilterOnly任一标志设置为false时,才会分析表内容。当两者都为true时,无需处理和生成图表。
- 将忽略空列的分析
- Metadata 属性 - columnData将使用列信息进行更新,该信息识别单元格文本在整个列中的总出现次数。此信息用于为此列生成“分组图表”。
- 同样,将进行唯一性检查,以查看任何列是否包含唯一记录。规则是 - *当上一步识别的单元格文本总数等于 HTML 表中的总行数时,该列为唯一列*。因此,它将被“分组图表”绕过。
 
- 这是使用 
- 为图表准备数据集
		- 这是使用 private方法 -prepareDataSets()完成的。数据集就是每种图表输入数据的格式。
- 数据集的内容将是 - 图表标题、X 轴标签、Y 轴标签、类别和计数
- 此方法将遍历元数据记录以准备数据集。
- 由于过滤条件,一个或多个列可能具有统一的值。这些值将用于识别数据的扩展分组。
- 此方法将根据已识别的一组统一值动态准备图表标题。
 
- 这是使用 
- 用所有可能的图表选项填充图表下拉框或显示错误消息
		- 这是使用 private方法 -report()完成的。
- 根据准备好的数据集,此方法将用所有可用图表的列表填充“可用图表”下拉框。
- 如果没有可能的图表,原因是所有记录都包含唯一值,此方法将显示错误消息,指出所有记录都不同。
- 用户可以选择合适的图表进行查看。
 
- 这是使用 
 
- 分析表头
		
- 下一步也是最后一步是根据用户的选择渲染图表。下拉框的 onchange事件将调用analyzer.draw()方法,并将选定的图表选项作为参数传递。如果选择了“操作”和“数字列”,则此方法将调用private internal方法 -updateDataSet(operation, numColumn, reportIndex)。此方法将执行所需的计算并更新将用于渲染图表的dataset。
历史
- 2013 年 1 月 10 日:初始发布。版本 1.0- 您可以从本文左侧的修订链接查看 1.0 版的详细信息。
 
- 2013 年 1 月 15 日:发布 2.0 版- 更改包括- 增加了对选择数学运算以生成图表的支持
- 删除了 JSChart库
- 默认情况下,图表将使用 Open Flash Chart 库显示
 
 
- 更改包括
- 2013 年 2 月 14 日:添加了演示网站链接
注意
如果您喜欢这篇文章,请评价它。同时,也请告诉我您对此的反馈。
如果您对要包含在此实用程序中的功能有任何建议,请告诉我,以便大家都能使用它。


