[HTML5-SVG]利用 SVG 在 Web 应用程序中创建客户端图表交互

42 篇文章 0 订阅
24 篇文章 0 订阅

本文给出一个具体的 Web 页面,Web 开发人员及其管理者都将会对它感兴趣。尽管代码编写理解起来足够简单,但是它建模了一个超出传统的基于表单的 Web 应用程序的 GUI 效果。此效果:

  • 只依赖于公共标准。
  • 执行起来至少跟专有备选方案一样好。
  • 开启了全新的团队合作和协作模型。
  • 给出一种以前肯定没有明确地做过文档化的实现技术。

本文有以下三个目标:

  • 从用户角度演示一个特定的标准兼容的基于 Web 的 GUI 效果的操作。
  • 从开发人员的角度解释协作模型,作为 Web 和 SVG 技术之间深入协作的一个例子。
  • 阐明 HTML5 如何促进复杂 Web 应用程序开发中新的劳动分工,因为团队领导者想要知道。

本文面向的读者群体是,他们能够很好地看懂 Web 页面的 HTML 和 JavaScript 典型代码,但是不必流利地用这些语言编写代码。无需 SVG 经验。必须熟悉 XML。尽管不依赖于特定的操作系统,但是希望输出到各种不同的浏览器。

一个实际例子

要运行本文中的例子,使用 Microsoft® Internet Explorer® 以外的一种现代浏览器:Safari、Opera、Chrome、Firefox 和 QtWeb 通常都不错。尽管至少有好几种有效的方式在 Internet Explorer 中运行本文的 SVG,但是简单地依赖于一种更加标准兼容的浏览器在编写本文期间还是更为可取的。

您有必要亲自体验一下此 Web 页面提供的效果。首先从我的 Web 站点查看本文重要的实际例子;链接在 参考资料 的第一项中。或者,也可以从 下载 部分下载源文件,解压,并在浏览器中打开 outside_in.html 文件。两种情况下,浏览器中都应该出现类似于 图 1的图像,其中所有 50 个州和美国属国都是一种颜色。整个美国的地图(带有维尔京群岛、关岛和哥伦比亚特区的插页地图)以单色显示,颜色代表这个国家的食品券参与率(food stamp participation rate)。在本例中,单色是红色,此时的参与率是 0.0%。


图 1. 当选择的阈值是 0.0 时美国食品券参与率的布色
整个美国的地图,包括其属国,全是红色

部分效果是它的动态响应。在实际例子中,将显示器顶部的滑块指针稍微向右移动一点(就是将鼠标指针放在它上面,按下鼠标左键拖动,然后释放鼠标左键)。您会看到标注为 threshold 的这个数字更新了,可能从 0.0 变为比如说 6.2 这样的值。马上,地图重新着色,以匹配新的阈值。地图布色的含义是:食品券参与率低于阈值的州都以白色显示,食品券参与率至少是阈值的两倍的州都以红色显示,食品券参与率为中间值(即大于阈值但小于阈值的两倍)的州以黄色显示。

快照

来看一个例子:2009 年 6 月,内布拉斯加州报告其居民使用食品券的比率是 7.8%。如果阈值设置为 0 到 3.9 之间的任何值,那么像图 2 中那样,内布拉斯加州显示为红色。在本例中,整个美国的地图(带有维尔京群岛、关岛和哥伦比亚特区的插页地图)将怀俄明州和新泽西州显示为黄色,所有其他州和属国显示为红色。


图 2. 当选择的阈值是 3.1 时美国食品券参与率的布色
整个美国的地图;所有州都是红色,只有怀俄明州和新泽西州是黄色

当阈值是 3.9 到 7.8 时,如 图 3 所示,内布拉斯加州显示为黄色。在本例中,整个美国的地图(带有维尔京群岛、关岛和哥伦比亚特区的插页地图)将内布拉斯加州和大多数州及属国显示为纯黄色,17 个州为纯红色,4 个州为纯白色。


图 3. 当选择的阈值是 6.9 时美国食品券参与率的布色
整个美国的地图;内布拉斯加州和大多数州及属国显示为黄色,17 个州为红色,4 个州为白色

对于任何高于 7.8 的值,这个州的颜色更改为白色。在 图 4 中,选择的阈值是 9.9。在本例中,整个美国的地图(带有维尔京群岛、关岛和哥伦比亚特区的插页地图)将17 个州和属国显示为纯白色,其余为纯黄色。


图 4. 当选择的阈值是 9.9 时美国食品券参与率的布色
整个美国的地图;17 个州和属国显示为纯白色,其余为纯黄色

由于 Threshold 字段中的值是动态变化的,所以州或属国的颜色会根据这个州的食品券参与率而改变。(查看 生动的例子。)在本例中,视图在以下阈值和颜色之间变化。

  • 0.0 阈值 - 所有州和属国都显示为纯红色(如 图 1 所示)。
  • 3.1 阈值 - 怀俄明州和新泽西州显示为纯黄色,所有其他州和属国为纯红色(如 图 2 所示)。
  • 6.9 阈值 - 大多数州和属国显示为纯黄色,17 个州和属国为纯红色,4 个州为纯白色(如 图 3 所示)。
  • 9.9 阈值 - 17 个州和属国显示为纯白色,其余为纯黄色(如 图 4 所示)。
  • 20.0 阈值 - 所有州和属国都显示为纯白色(如 图 5 所示)。

动机

SVG 利用其支持的复杂动画建立最强烈的即时印象。这些内容在其他地方有解释,您可以在 参考资料 中找到到这些文章的链接。

本文的思路比较微妙,如果您首先观察一位知识渊博的人用图形表示他在物理空间和时间内移动的轨迹,通常会更容易理解本文内容。它取决于两个 方向流入的信息,既从图表进入您的眼睛,也通过鼠标指针从您的大脑到达实况图。

注意您调整阈值时出现的地理图案。这种业务智能通常只通过可视化而可用。重要的交互式(interactive)概念很强大,就跟第一代计算机电子表格支持的所有 what-if 场景一样:它为理解底层的主题提供一个不可改变的动态 维度,不管是食品券参与率的地图,还是地震中心附近的应力分布图。

但是直到最近,动态图形交互很大程度上只是专有或桌面应用程序的领域。正如本文所展示的,SVG 现在为 Web 应用程序高级的、基于标准的效果打下了良好的基础。SVG 和更通常的简称为 HTML5 的功能集合为 Web 应用程序开发打开了一个崭新的领域。

下一节解释您现在作为用户能看懂的食品券参与率显示图背后的实现。

代码解释

现在来看创建 SVG 显示的代码

材料清单

本例的基本架构涉及到两个源文件:

  • outside_in.html 定义应用程序的绝大部分。
  • usa_map.svg 是美国的一个基本地图,编码为 SVG,从 outside_in.html 引用它。

这两个文件都编写为人类可读懂的;您完全可以尝试着在浏览器中打开它们,研究一下源文件。

例子的当前实现实际上将 outside_in.html 各个部分分段为多个 JavaScript .js 源文件。就目前了来说,这只是为了方便起见;将它们看作 .html 源文件的一部分,或者更精确地说,看作不受 SVG 影响的源组织的一个方面。根据通常的软件工程原则划分 .html 和 .js 源文件。

但是 usa_map.svg 是独立的:您的浏览器可以单独加载它,就像您会单独查看 GIF、JPEG、PNG、TIFF 或其他图像格式一样。浏览器首次加载 foodstamps.html 时,只是将 usa_map.svg 当作一个图像,并构造一个可显示的页面,地图作为嵌入式图形对象。这是 <object> 元素的效果:


清单 1. HTML 中对 SVG 的引用

				
    <div style = "position:absolute;left:0px; top:60px">
    <object id = "map" type = "image/svg+xml" data = "usa_map.svg"
            width = "1050" height = "600"></object>
    </div>

结果是让浏览器显示内容类似于 图 5,其中所有 50 个州和美国属国都以单一颜色显示。在本例中,整个美国的地图(带有维尔京群岛、关岛和哥伦比亚特区的插页地图)显示为纯白色。


图 5. 任何动态布色之前的地图
整个美国的地图及其属国都显示为白色

开始解释脚本编写

但是您的浏览器若支持 JavaScript 脚本,那么它的工作就还没完。onload 浏览器事件触发 JavaScript 初始化,从而:

  • 将食品券数据存储在一个方便的表单中;
  • 激活显示器顶部的滑块小部件;

最重要的是,还获得一个到 SVG 实例的 DOM 的句柄。

通过该句柄,JavaScript 然后可以访问 SVG 的单个元素以及这些元素的特定属性,直到为单个州的背景布色的层次:


清单 2. 从外围 HTML 访问 SVG 属性

				
    function color_map(lower_level) {
        var map = document.getElementById('map');
        var svg_document = map.contentDocument;
        // Typical values for abbreviation:  'AK', 'AL', ...
        for (var abbreviation in big_table) {
            this_state = svg_document.getElementById(abbreviation);
            //  ...
            //  this_color has a value such as "red", "white", or "yellow".
            this_state.setAttribute("style", "fill:" + this_color);
        }
    }

这里传递给 getElementById() 的 ID map 就是 清单 1 中 object 的 ID。SVG 实例在 HTML DOM 中具有该 ID。但是要到达单个州并为其布色,您是在 SVG 的 DOM 中导航,该 DOM 在 清单 2 中作为 svg_document 出现。svg_document 一旦分配,就可用于编写脚本,方式完全跟利用 document 为单独的 SVG 编写脚本相同。但是要注意,可以说 document 是一个关键词,因为每种浏览器都保证它的值,而 svg_document 只是稍微与之类似,它的值是在这个特定的程序中由 color_map 函数定义中的局部赋值分配的。

回页首

SVG 的作用

SVG 如何与编程协作呢?很少需要它;地图中单个州的区域被分配熟悉的 ID('AK'、'AL'、……'WY'),以便容易引用:


清单 3. SVG 中一个元素的源代码

				
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <svg
       version="1.0"
       width="958.69"
       height="592.78998"
       id="svg8834"
          ...
        <path
           d="M 486.79838,390.07686 L 488.12421,392.50754 ..."
           id="NE"
           style="fill:#FFFFFF " />
           ...
    </svg>

注意,该 SVG 实例没有 嵌入脚本编程。再次强调:尽管此食品券例子本质上是关于 SVG 脚本编程,但是根本没有 脚本代码出现在 SVG 源代码本身中。据我所知,这种由外而内(outside-in)的 SVG 脚本编程技术以前还没有清楚地文档化过,即使不同的浏览器已经支持它多年了。

SVG、HTML 和 XML

要清楚地理解 SVG 在 Web 应用程序中具有的潜能,您一定得明白 XML 在 SVG 和 Web 专家之间扮演的稍微不同的角色。

就这点来说,工作在 SVG 和 Web 中的相同之处相当少。尽管 Web 浏览器是分布最广的 SVG 呈现器,但是 SVG 专家通常不把关注点放在传统的 Web 应用程序上。其中一个后果就是,缺少对 “由外而内” 脚本编程的文档化。

另一个后果是,Web 和 SVG 专家谈论 XML 知识时偶尔会出现混淆。对于 Web 工作人员来说,XML 是一种选择:他们可以选择以比如说 XHTML 方式思考,但是也存在备选方式。无论哪种情况,浏览器在 HTML 解析上多少有点宽容。

对于 SVG 来说不是这样的。SVG 是一个 XML 应用程序。如果一个 .svg 源文件不是格式良好的 XML,不可解析为有效的 SVG,那么它就是没有用的。尽管大家可能会推测潜在的 SVG 解析器,但是这里不进行这方面的讨论。

这个充斥市场的 Web 浏览器接受广泛的类似于 HTML 的输入,在呈现 SVG 时通常相当严格。SVG 实例和 Web 文档都是以 DOM 的形式编写脚本的,并且两种 DOM 都可序列化为 XML。尽管有这些类似之处,但是单个浏览器中的解析器一般是各不相同的,某种程度上讲,从业者都必须单独学习。

劳动分工

跟本文的由外而内代码编写一样有趣,并且它的应用都是从技术角度出发的,它们最大的影响可能在管理方面。可以用智能 Shockwave 或 HTML5 canvas 编码产生相同的可视效果。但是这些备选方案没有哪一个能像这里的 SVG 技术那样带来明显的劳动分工。

好于 MVC 或呈现与内容

软件工程的基本原则之一是,明智的设计导致不同模块之间的耦合低,这些模块然后可能要被相对独立地进行维护、改进及管理等。这就是模型-视图-控制器和呈现-内容被认为是好东西的主要原因。

SVG 的范围比其他划分要窄得多。但是我发现它特别满足我的工作需要。利用这里的编码,地图专家可以独立于 JavaScript 代码编写者来制作地图。如 前一节 所述,两种开发人员之间的链接点就是,对单个地理单元的 XML ID 的认可。很容易为彻底不同的应用程序重用地图 — 大家可能都没设想过地图第一次创建的时候是什么样的 — 或者将相同的脚本代码应用于不同的地图。

这个脆弱的链接可能会比最初更弱。不同的工件可以存活在不同的服务器上,出于安全性或经济原因,只在浏览器中第一次会合。医学图像可能在一个国家被编码为 SVG,诊断知识库在另一个国家开发,将二者合到一起的 Web 应用程序则在第三个国家出现。

定制小部件

该主题的另一个变体是,它为基于 SVG 的小部件带来了市场 机会,基于 SVG 的小部件类似于 JavaScript 编码的库的现有小部件。可以用内部脚本(用于创建一些有趣的效果)编写 SVG,但是同时也提供外部应用程序编程界面。这导致一种在小部件生产中利用 SVG 内置优势(可伸缩、高效率,等等)的良好方式。

SVG、HTML 和 XML 小节中,我提到过 XML 在 HTML 和 SVG 中的不同角色。弄清楚这一区别有助于组织工作。Web 开发人员完全可以自由地使用 SVG 小部件或图表,无需自己知道如何编写格式良好的 XML。相反,SVG 专家可以开发他们的地图,无需负责不同浏览器之间 <embed> 和 <object> 各自不同的约定。

另一种来自其他管理模型的区别也值得解释。像 Java™ 和 C++ 这样的语言通常按照系统开发人员(他们编写库)和应用程序程序员(他们使用这些库)来进行组织。对于 SVG 也可以这样,HTML5 则更为广泛。但是,至少在 2010 年为 SVG 交付的工件一般是源代码。Java 技术编译 它的库,并强调信息隐藏。根据同样的机制,SVG 的现有实践不保护知识产权。关于牵连(implications)的完整讨论超出了本书范畴。

拓宽 DAAS 趋势

随着数据即服务的兴起,SVG 将支持更广泛的可视化,可视化将方便地从特定内容去耦合。在 Web 的早期,惟一支持本文说明的这类交互的工具是图像地图和专有插件。前者编写起来特别乏味,维护起来就更难了。相反,SVG 充当一种更高级别的语言,用于开发广泛的图像效果。

其他主题

尽管 SVG 只是 XML 的一个独立分支,但是它已经成长得太大了,要完全了解它不是那么容易了,谈何在一篇文章中详细介绍它的各个方面。有不少主题会让本文读者感兴趣,但是仍然超出了本书范畴。对大多数此类主题,都已经可以找到很好的资料(参见 参考资料)。

  • SVG 介绍,包括如何编写 SVG 实例;
  • HTML 页面中不同风格的嵌入式 SVG 图像;
  • 高级 SVG 主题,包括定制小部件的动画和构造;
  • SVG 样式,尤其是与 SVG 结合使用 CSS;
  • XML,尤其是那些用于 Web 应用程序的工件(比如 XHTML 和 SVG)的所有权;
  • JavaScript
  • HTML5

结束语

由外而内的 SVG 脚本编程允许高级可视效果,容易编写代码。该技术也鼓励良好的模块化,这最小化了可视元素和作用于这些元素之上的应用程序逻辑之间的耦合。

回页首

致谢

SVG 到撰写本文时还只取得阶段性成功,这一切得益于很多有想法的分析师和程序员的贡献。难以用语言来说出他们在过去 10 年间将 SVG 向前推进了多远。

本文中使用的特定美国地图最初灵感来自于 Wikipedia 在 Creative Commons ShareAlike License 下提供的一幅地图。

回页首

下载

描述名字大小下载方法
本文的源代码包SVG_foodstamp_tutorial.zip106KBHTTP
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值