简介
随着 Web 2.0 的日益流行,web 开发库(比如 Dojo 和 jQuery)正在变得越来越重要。web 页面变得越来越像应用程序。使用 Dojo 的制图模块,您可以快速轻松地将外观美观、功能强大的动态图表和曲线图添加到您的 web 页面。
在本文中,了解如何使用 dojox.charting 模块的许多特性。示例和代码样例将详细展示新的 Dojo Toolkit 1.5 中的制图特性。
回页首 图表概览
本节提供 Dojo 可视化库提供的主要图表类型的一个概览。
线形图
使用基本的线形图,您可以绘制线条并在数据点上放置标记。有几种类型的线形图:
- Default:通用线形图能够绘制线条,填充线条下面的区域,并在数据点上放置标记;如果在添加到绘图区时没有指定绘制类型,将使用这种类型。
- Lines:基本线形图;与 Default 配合使用
- Areas:数据线下方的区域被填充;与 Default 配合使用
- Markers:带标记的线条;与 Default 配合使用
- MarkersOnly:只有标记,没有线条;与 Default 配合使用
图 1 展示了一个带标记的线形图示例。
图 1. 带标记的线形图
堆叠线形图
堆叠线形图的选项包括:
- Stacked:绘制的数据集与前面的数据集相关;Default 类型的扩展
- StackedLines:使用线条的堆叠数据集;与 Stacked 配合使用
- StackedAreas:图表线条下方区域填充的堆叠数据集;与 Stacked 配合使用
例如,图 2 展示了一个堆叠区域图,拥有图表线条下方区域填充的堆叠数据集。
图 2. 堆叠区域图
条形图
经典条形图拥有以下选项:
- Bars:水平条
- ClusteredBars:带有聚簇数据集的水平条;与 Bars 配合使用
- StackedBars:带有水平条的堆叠数据集;与 Bars 配合使用
柱形图
柱形图有以下几种类型:
- Columns:垂直条
- ClusteredColumns:带有聚簇数据集的垂直条;与 Columns 配合使用
- StackedColumns:带有垂直条的堆叠数据集;与 Columns 配合使用
例如,聚簇柱形图拥有带有聚簇数据集的垂直条,如图 3 所示。这是一个比较复杂的柱形图。
图 3. 聚簇柱形图
堆叠柱形图是另一个种复杂柱形图。它们显示带有垂直条的堆叠数据集,如下所示。
图 4. 堆叠柱形图
其他类型
下面是其他类型的图表:
- Pie:也许是最常见的图表类型之一
- Scatter:类似于 MarkersOnly,但支持使用渐变区域绘制
- Grid:用于向图表添加一个网格层
饼图是一个分为多个扇区的圆形图表,扇区代表各个组成部分。
图 5. 饼图
地图图表
在一个地图图表中,您可以基于地理数据绘制地图。在本文末尾进一步了解 地图图表。
图 6. 地图图表
回页首 使用 Dojo 制图
本节简要介绍 Dojo 制图的一些特性。
清单 1 展示使用 Dojo 可视化库创建图表的基本方法。有 4 种方法:addAxis 、addPlot 、addSeries 和
render 。
清单 1. 使用 Dojo 可视化库创建图表的基本方法
<div id="test1" style="width: 200px; height: 200px;"></div>
makeObjects = function(){
var chart1 = new dojox.charting.Chart2D("test1");
chart1.addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true});
chart1.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major",
natural: true});
chart1.addPlot("default", {type: "Bars"});
chart1.addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "red"},
fill: "lightpink"});
chart1.addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"},
fill: "lightblue"});
chart1.render();
};
dojo.addOnLoad(makeObjects);
|
要配置图表,需要定义三个必要部分:
- 绘图区
- 描述数据如何可视化;例如,一个柱形图、条形图或饼图
- 轴
- 描述正在被可视化的数据的维度;这是 X 轴或 Y 轴定义,包括指定标签文本和标签旋转等选项
- 系列数据
- 描述图表将可视化的数据
绘图区配置
addPlot() 函数接受两个参数:一个名称和一个参数数组。当您的绘图区上需要一个以上的图表类型时,名称作为标识符。参数数组包含您的绘图选项,这取决于您使用的绘图类型。
addPlot("default", {type: "Areas", tension:"X"})
|
指定轴
使用 addAxis() 方法来指定图表轴。图表上的 addAxis() 调用拥有几个用来定义轴的选项。与 addPlot() 类似,这个调用接受两个参数:一个名称和一个选项数组。您需要使用默认值 x 和 y 作为您的轴名称,除非您在 addPlot() 调用中提供了自定义名称。
如果您想创建包含一个轴或不包含轴的图表,则不必定义轴。也可以通过添加第二个绘图区并将轴附加到它来创建带有超过两个轴的图表。使用这种方法,可以通过使用 2 到 4 个绘图区在 addAxis() 中设置一个 leftBottom 参数来显示最多 4 个不同的轴(两个垂直轴和两个水平轴)。
单个轴也可以被多个绘图区共享。两个绘图区可以使用相同的水平轴,但拥有不同的垂直轴。清单 2 展示了这种情况的所有 addPlot() 选项。
清单 2. addPlot()
选项
chart.addAxis("x2", {fixLower: "minor", natural: true, leftBottom: false,
stroke: "grey", majorTick: {stroke: "black", length: 4}, majorLabels: true});
chart.addAxis("y2", {vertical: true, min: 0, max: 20, leftBottom: false,
stroke: "grey", majorTick: {stroke: "black", length: 4},
minorTick: {stroke: "gray", length: 2}});
chart.addPlot("plot2", {type: "Areas", hAxis: "x2", vAxis: "y2",
animate: {duration: 1800}});
|
启用和禁用刻度标记
可以在微观和宏观级别打开和关闭刻度标记。也可以在主要和次要级别打开和关闭标签。例如,如果 majorTick 不为 false,您的图表将沿着轴显示刻度标记。
标签参数类似于刻度标记。如果 majorLabels 等于 false,您的图表将显示对应刻度的标签,即使您已经设置了标签文本。参见上面的清单 2。
使用自定义轴标签
Dojo 图表支持向任意轴分配自定义标签。确保在您的 div 中预留足够的空间,以便文本能够正确显示。清单 3 展示如何在柱形图中使用缩写的月份名称。
清单 3. 在柱形图中使用缩略月份名称
chart4.addAxis("y", {
vertical: true,
fixLower: "none",
fixUpper: "none",
natural: true,
majorTick: { length: 3 },
labels: [
{value: 0, text: ""},
{value: 1, text: "January"},
{value: 2, text: "February"},
{value: 3, text: "March"},
{value: 4, text: "April"},
{value: 5, text: "May"}
]
});
|
系列配置
addSeries() 用于定义图表上显示的数据集。addSeries() 接受三个参数:一个名称、一个数据数组和一个选项数组。当您想刷新数据时,还有一个 updateSeries() 调用,接受一个名称和数据数组。
addSeries() 调用的选项有:
-
stroke 指定您的条形图和柱形图的线条或边界的颜色和宽度。 fill 指定区域线形图中的线条下方的填充区域的颜色,以及条形图和柱形图的条填充颜色。
如果您熟悉 SVG 或 dojox.gfx,就能识别 stroke 和 fill 。
addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "red"},
fill: "lightpink"})
|
数据数组有时只是一系列数据。所有图表类型都可以接受一个一维数组,但根据不同的图表类型,还有其他一些格式选项。使用线形图的一维数组,X
轴将是整数(1、2、3...),数据将是 Y
轴。对于条形图,数据是条的长度,柱形图和条形图之间的选择决定条的方向。对于饼图,数组之和是整个饼。所有图表类型(除了饼图)都可以拥有多个系列。
清单 4. addSeries() 实际应用
addSeries("Series A", [
{ x: 0.5, y: 5 },
{ x: 1.5, y: 1.5 },
{ x: 2, y: 9 },
{ x: 5, y: 0.3 }
]).
addSeries("Series B", [
{ x: 0.3, y: 8 },
{ x: 4, y: 6 },
{ x: 5.5, y: 2 }
])
|
对于饼图,您可以指定额外的信息,比如:每个块的文本标签、每个块的颜色、以及覆盖在 addPlot() 调用中定义的前景颜色的前景颜色。清单 5 展示了一个示例。
清单 5. 一个饼图的 addSeries()
chart6.addSeries("Series A", [
{y: 4, text: "Red", color: "red"},
{y: 2, text: "Green", color: "green"},
{y: 1, text: "Blue", color: "blue"},
{y: 1, text: "Other", color: "white", fontColor: "black"}
]);
|
图表事件
Dojo 制图拥有自己的附加事件的方法。connectToPlot 是一个非常有用的事件处理方法。图表事件允许您将行为附加到各种图表特性,比如标记,以响应用户动作。受到支持的事件包括:
onclick onmouseover -
onmouseout
事件处理程序可以附加到一个图表的单独绘图区,如清单 6 所示。
清单 6. 可以附加到一个图表的单独绘图区的事件处理程序
chart1.connectToPlot("default", function(args){
switch(args.type){
case "onclick":
if(args.index == 1){
var shape = args.shape;
//TODO...
}
break;
case "onmouseover":
//TODO...
break;
case "onmouseout":
//TODO...
break;
default:
//TODO...
break;
}
});
|
缩放
Dojo 制图提供了一些方法来控制缩放,以向下钻取到您的图表的最小细节,包括滚动和平移(使用您的鼠标在两个维度上移动图表)。注意,平移可能会使浏览器到达极限,但新一代浏览器(Firefox
3、Safari 3、Opera 9.5)能够胜任这个任务。Dojo 制图现在也有可以改善用户体验的缩放动画效果。
chart.zoomIn("x", [50, 80]);
//zoom into [50, 80] which is part of total zone [0, 100] on x axis
|
回页首 动作和动画效果
动作是自含式对象,当用户与图表交互时,动作使用一些事件来实现某种效果。通常,它们旨在吸引注意力并表明选择了哪个图表元素,或者显示其他信息。
这个默认库包含了以下 5 个动作:Highlight、Magnify、MoveSlice、Shake 和 Tooltip。它们都利用 Dojo 动画支持。
- Highlight
- 当用户将鼠标悬停于一个元素上方时,此动作突出显示(通过修改填充来更改颜色)图表的单独元素;受影响的元素包括:标记、垂直条、水平条、圆圈和饼图切块。
var anim1c = new dc.action2d.Highlight(chart1, "default", {
duration: 2000,
easing: dojo.fx.easing.sineOut,
highlight: "blue"
});
|
- Magnify
- 当用户将鼠标悬停于一个单独元素上方时,此动作扩大图表中的那个元素;这个效果总是与突出显示效果连用。受影响的元素包括标记和圆圈。
var anim9a = new dc.action2d.Magnify(chart1, "default", {
scale: 1.5
});
|
- MoveSlice
- 此动作将切块移出饼图;当用户将鼠标悬停于一个元素上方时,此动作实际上是使切块略微偏离其 x 和 y 轴位置。
var anim10a = new dc.action2d.MoveSlice(chart10, "default", {
scale: 2,
shift: 5
});
|
- Shake
- 当用户将鼠标悬停于一个元素上方时,此动作绘制元素;受影响的元素包括:标记、垂直条、水平条、圆圈和饼图切块。
var anim6b = new dc.action2d.Shake(chart6, "default"{
shiftX: 5,
shiftY: 10
});
|
- Tooltip
- 显示一个工具提示,但它实际上是一个带有一些位置定制的 dijit.Tooltip;当用户将鼠标悬停于一个绘图元素上方时,它总是锚定在中间。受影响的元素包括:标记、垂直条、水平条、圆圈和饼图切块。
var anim1b = new dc.action2d.Tooltip(chart1, "default", {text: function(args){
return args.index < 2 ? "good" : "bad";
}});
|
工具提示内容可以针对不同的功能定制。
图表小部件
使用 Dojo 最简单的方法之一是使用 Chart2D 小部件。使用 dojo 图表小部件的方法与使用 dojo 标准小部件的方法相同。使用 dojoType =
‘dojox.charting.widget.chart2D’ 将其嵌入到 HTML 源代码中,而不是以编程方式创建一个 dojo 图表小部件。清单 7 源自一个 Dojo Chart2D 小部件测试。
清单 7. 一个 Dojo Chart2D 小部件测试
<div dojoType="dojox.charting.widget.Chart2D" id="chart1"
style="width: 300px; height: 300px;">
<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
font="italic normal normal 8pt Tahoma"></div>
<div class="plot" name="default" type="Areas"></div>
<div class="plot" name="grid" type="Grid"></div>
<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
<div class="series" name="Run B" array="seriesB"
legend="<em>Custom</em> legend"></div>
<div class="series" name="Run C" store="tableStore" valueFn="Number(x)"></div>
</div>
|
图表图例小部件
图表图例小部件是 Dojo 图表用于图例渲染的一个独立小部件。可以使用 dojox.charting.widget.Legend 将一个图例小部件添加到您的图表。图例自动提取其附加到的图表的形状标记和颜色。默认情况下,图例小部件使用一个系列的 legend 参数。如果没有指定图例,那么它恢复为 name 参数。
对于饼图,图例的行为不同。如果使用一个数字数组指定图表,那么它将使用数字。否则,它将按以下顺序检查对象属性:legend 、text 和数值。
var legend1 = new dc.widget.Legend({chart: chart1, horizontal: true}, "legend1");
|
回页首 Dojo
Toolkit 1.5 特性
本节简述 Dojo Toolkit 1.5 的一些与制图相关的新特性。
地图图表
Map 小部件 dojox.geo.charting.Map 是一个很好的新小部件,支持在 web
页面上轻松创建地图。地图图表支持包含针对每个地图特性的详细信息的数据。每个地图都可以被划分为几个特性;比如,一个特性可以是基于一个世界地图的国
家,或者基于一个国家地图的省份。您还可以定制每个地图特性的工具提示数据。对于每个特性,提供了缩放效果和定制的交互式事件。
清单 8 展示了地图图表小部件的一个测试用例。
清单 8. 地图图表小部件的测试用例
dojo.require("dojox.geo.charting.Map");
dojo.addOnLoad(function(){
var USStates = new dojox.geo.charting.Map("USStates",
"../resources/data/USStates.json");
USStates.setMarkerData("../resources/markers/USStates.json");
});
|
在上面的示例中,USStates.json 是地图图表数据源。清单 9 展示了内容,其中包括描述详细数据的注释。
清单 9. 包括注释的地图图表代码
new dojox.geo.charting.Map(container, shapefile)
// container
// map container html node/id
// shapefile
// map shape data url, handle as json
shapefile data format:
{
//layerExtent: map boundary
"layerExtent":[0, 0, 8036, 5263],
//"featureNames: list of map unit, like a province in a country map
"featureNames":["RI", "VT", "HI", "ME", "VA", "MI", "DE", "ID", "IA", "MD", "MA",
"AR", "IL", "UT", "IN", "MN", "AZ", "MO", "MT", "MS", "NH", "NJ", "NM", "AK", "TX",
"AL", "NC", "ND", "NE", "NY", "GA", "NV", "TN", "CA", "OK", "OH", "WY", "FL", "SD",
"SC", "CT", "WV", "DC", "WI", "KY", "KS", "OR", "LA", "WA", "CO", "PA"],
//features: map unit shape info
"features":{
"RI":{
//unit shape vertex described in polygon: [[polygon1_vertex1_x,
polygon1_vertex1_y, p_v2_x, p_v2_y, ...], [p2_v1_x, p2_v1_y, ...], ....]
"shape":[[7641, 1436, 7651, 1437, 7661, 1467, 7661, 1467, 7653, 1478, 7641,
1436], [7541, 1398, 7559, 1392, 7598, 1380, 7615, 1420, 7635, 1430, 7635, 1431, 7627,
1445, 7626, 1427, 7615, 1429, 7607, 1410, 7618, 1435, 7606, 1444, 7617, 1460, 7618,
1506, 7612, 1496, 7568, 1527, 7568, 1526, 7541, 1398], [7633, 1474, 7639, 1442, 7645,
1476, 7631, 1485, 7633, 1474]],
//center: center point
"center":[7585, 1442],
//shape's rectangle boundary
"bbox":[7541, 1380, 120, 147]
},
"VT":{
"shape":[7427, 828, 7434, 848, 7424, 882, 7445, 909, 7444, 926, 7390, 984, 7404,
1022, 7383, 1128, 7402, 1236, 7394, 1266, 7414, 1289, 7393, 1294, 7309, 1313, 7302,
1314, 7267, 1166, 7255, 1151, 7239, 1162, 7241, 1126, 7216, 1076, 7218, 999, 7196,
969, 7184, 893, 7202, 888, 7427, 828],
"center":[7317, 1057],
"bbox":[7184, 828, 261, 487]
},
.......
}
}
|
图 7 展示了 web 页面上显示的地图图表。
图 7. 简单地图图表
渐变和模式
新的 Dojox 制图渐变特性能在图表上提供一种美观的渐变填充效果。这个渐变特性能够在图表主题内定制,它基于图表和形状。它还提供线性和放射状渐变样式。
图 8 展示了不同的渐变效果。
图 8. 线性和放射状渐变
图 8 中的第一个图表在每个形状上渐变。中间的图表在绘图区上渐变。它们都是线性渐变。图 8 中的最后一个图表是一个放射状渐变。清单 10 展示了这个示例的代码。
清单 10. 渐变效果代码
var theme1 = new dojox.charting.Theme({
seriesThemes: [
{
fill: {
type: "linear", space: "plot", x1: 0, y1: 0, x2: 100, y2: 100,
colors: [{ offset: 0, color: "white" }, { offset: 1, color: "red" }]
}
},
{
fill: {
type: "linear", space: "plot", x1: 0, y1: 100, x2: 100, y2: 0,
colors: [{ offset: 0, color: "white" }, { offset: 1, color: "blue" }]
}
},
{
fill: {
type: "linear", space: "plot", x1: 0, y1: 0, x2: 100, y2: 100,
colors: [{ offset: 0, color: "white" }, { offset: 1, color: "green" }]
}
}
]
});
var chart1 = new dojox.charting.Chart2D("c1").
setTheme(theme1).
addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major",
includeZero: true, minorTickStep: 0.5}).
addPlot("default", {type: "Columns"}).
addSeries("Series A", [1, 2, 3, 4, 5]).
addSeries("Series B", [5, 4, 3, 2, 1]).
render();
|
可以看出,这些渐变都在 theme1 中定制。fill 参数类型可以是 linear 或 radial ,空间可以是 plot 或 shape 等。清单 11 展示了细节。
清单 11. 使用 fill
参数的渐变效果
seriesThemes: [
{
fill: {
// summary: fill for plot1
// type: string:
// gradient fill type e.g. “linear”, “radial”
// space: string:
// gradient fill area e.g. “plot”, “shape”, “shapeX”
// x1: Number:
// gradient fill start point offset percentage(0-100) for x Axes
// x2: Number:
// gradient fill end point offset percentage(0-100) for x Axes
// y1: Number:
// gradient fill start point offset percentage(0-100) for y Axes
// y2: Number:
// gradient fill end point offset percentage(0-100) for y Axes
// colors: Array
// gradient fill settings
type: "linear", space: "plot", x1: 0, y1: 0, x2: 100, y2: 100,
colors: [{ offset: 0, color: "white" }, { offset: 1, color: "red" }]
}
},
{
fill: {
type: "linear", space: "plot", x1: 0, y1: 100, x2: 100, y2: 0,
colors: [{ offset: 0, color: "white" }, { offset: 1, color: "blue" }]
}
},
{
fill: {
type: "linear", space: "plot", x1: 0, y1: 0, x2: 100, y2: 100,
colors: [{ offset: 0, color: "white" }, { offset: 1, color: "green" }]
}
}
]
|
定制模式的方法与定制渐变的方法相同。
使用为渐变提供的 API,可以定制许多视觉效果很好的复杂渐变效果。图 9 展示了条形图上的一个复杂渐变效果。
图 9. 条形图上的渐变效果
回页首 结束语
本文提供了 Dojo 可视化库中的主要图表类型的概览。您了解了一些流行图表的基本用法,比如绘图区、轴和系列。本文探索了缩放、动作和动画效果。您还了解了 Dojo 1.5 的一些新的地图和绘图特性。
参考资料 学习 获得产品和技术 讨论
关于作者  周
翔 是 IBM 中国上海 UT / Dojo 部门的一名软件工程师,之前在 IBM Lotus Mashups 部门 和 UT / Click
Track 部门工作,现在是 FIT / Dojo 部门的一员,主要从事 Dojo 控件库的研发工作,包括 Dojo
的claro主题的开发,dojox的可视化组件的开发。
|