使用 Apache Hadoop 和 Dojo 降低商业智能成本,第 2 部分: 使用 Dojo 工具包创建引人注目的、交互的报告

利用 Dojo 图表

理解您的业务总是很重要。您的公司能够像您希望的那样敏捷,但如果您不知道该采取什么正确步骤,那么您就像是 “在闭着眼睛开车”。商业智能解决方案可能成本高昂,并且它们通常需要您改进您的数据以适应它们的系统。但是,开源技术使得创建您自己的商业智能报告比以前任何时候都更容易。本文是系列的第二部分,您将了解如何利用由 Apache Hadoop 生成的商业智能数据通过 Dojo 工具包创建吸引眼球的、具有互动性的分析报告。

Michael Galpin, 软件架构师, eBay

Michael_Galpin 的照片 Galpin 是 eBay 的一名架构师,经常为 developerWorks 撰写文章。他曾在各类技术会议上发表演说,这些会议包括 JavaOne、EclipseCon 和 AjaxWorld 等。要了解 Michael 的工作进展,请您在 Twitter 上跟随 @michaelg 。



2011 年 7 月 06 日

先决条件

在本文中,您将使用通过本系列 第 1 部分 的 Apache Hadoop 创建的数据。本文的重点是关于 Dojo 工具包的使用(本文中是 1.4 版)。在示例中,您将使用 Google 的 Ajax API 将 Dojo 下载到您的页面上(请参考 参考资料),所以不需要下载 Dojo。在技能方面,您主要需要具有 JavaScript 经验。要获得这些工具的链接,请参考 参考资料

使用 Dojo 的图形报告

在本系列的 第 1 部分 中,您已看到了如何使用 Apache Hadoop 处理大型数据。在示例中,您使用 Hadoop 处理 Apache web 服务器访问日志。使用 Hadoop 将这些日志转化为商业智能数据,该数据将会告诉您 web 站点的用户正在使用什么浏览器来访问您的站点。通过 Hadoop 您所作的有用的事情之一是将此数据格式化为 JSON,因为您知道您最终将要编写一个 web 应用程序,该应用程序将使用此数据并将其转化为图形报告。清单 1 显示了一些您将在本文中使用的示例数据。

清单 1. 示例浏览器用法数据
[
    {"month" : "January 2010", "data": 
        {"IE8":5339680,"IPHONE":176397,"SAFARI":1161063,
        "FF35":5334121,"OTHER":1697189,"IE6":2355910,"OPERA":293024,
        "IE7":3448568,"FF3":1425939,"CHROME":1381381}},
    {"month" : "February 2010", "data": 
        {"IE8":4420267,"IPHONE":122378,"SAFARI":937765,
        "FF35":4904831,"OTHER":1249727,"IE6":1824138,"OPERA":261245,
        "IE7":2548741,"FF3":848517,"CHROME":1122684}},
    {"month" : "March 2010", "data" : 
        {"IE8":4832154,"IPHONE":124723,"SAFARI":1004835,
        "FF35":5240639,"OTHER":1443493,"IE6":1782140,"OPERA":288338,
        "IE7":2705560,"FF3":728227,"CHROME":1250771}},
    {"month" : "April 2010", "data" : 
        {"IE8":6014148,"IPHONE":153317,"SAFARI":1184909,
        "FF35":6355369,"IE6":2023596,"OTHER":1701331,"OPERA":336320,
        "IE7":3083772,"FF3":794613,"CHROME":1895022}},
    {"month" :"May 2010", "data" : 
        {"IE8":3985522,"IPHONE":107109,"SAFARI":826693,
        "FF35":4443157,"OTHER":1350928,"IE6":1169420,"OPERA":230201,
        "IE7":2032111,"FF3":471397,"CHROME":1358771}},
    {"month" :"June 2010", "data" : 
        {"IE8":4944664,"IPHONE":143594,"SAFARI":597916,
        "FF35":5396690,"OTHER":1740354,"IE6":1367462,"OPERA":264916,
        "IE7":2318786,"FF3":511660,"CHROME":1594828}}
]

这是由本系列 第 1 部分 中所开发的 Hadoop 作业生成的数据。在此示例中,您将直接在 web 页面上包括该数据,但是将其包括在使用 Ajax 可以下载的单独文件中会更便利。正如您从 清单 1 中所看到的,您有六个月以 JSON 表示的浏览器统计信息。Web 应用程序可以很容易地使用该数据来创建报告。

有许多优秀的服务器端和客户端的框架和库,您可以使用它们根据此数据创建报告。要使您的报告具有高度交互性,您需要一个客户端解决方案,Dojo 工具包就非常适合。它具有二维和三维图表。对于本示例来说,我们将使用二维图表。清单 2 显示了如何创建基本图表。

清单 2. 用 Dojo 创建基本扇形图
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hadoop Reports</title>
<script type="text/javascript"
    src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js"
    djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
    dojo.require("dojox.charting.Chart2D");
    var pieChart = {};
      var stats; // see Listing 1 for the stats
    function init(){
        pieChart = new dojox.charting.Chart2D("pie-chart");
        pieChart.addPlot("default", {
            type: "Pie",
            radius: 300,
            fontColor: "black",
            labelOffset : "-50"
        });
        var lastMonth = stats[stats.length -1];
        pieChart.addSeries("browsers", makePieSeries(lastMonth.data));
        pieChart.render();
    }
    function makePieSeries(data){
        var series = [];
        var total = 0;
        var key = "";
        for (key in data){
            total += data[key];
        }
        var label = "";
        for (key in data){
            label = key;
            label += " : ";
            label += data[key] * 100.0 / total;
            label += "%";
            series.push({y:data[key], text:label});
        }
        return series;            
    }
    dojo.addOnLoad(init);
</script>
</head>
<body>
<div id="pie-chart" style="width: 800px; height: 750px;"></div>
</body>
</html>

清单 2 中要首先要查看的就是脚本块。请注意您使用 Dojo 的包管理系统(dojo.require)来下载 Dojo 的 2D 图表对象,即 dojox.charting.Chart2D。在 web 页面完成加载时,脚本块的最后一行使用 dojo.addOnLoad 函数来调用函数(在本例中是 init 函数)。在 init 函数中,您创建扇形图并在字符串 pie-chart 中将其传递给构造函数。这将告诉 Dojo 要寻找具有 ID pie-chart 的 HTML 元素并将其用作将要创建的图表的父元素。您可以在 清单 2 中的 HTML 结构中看到此元素。

返回到 init 函数,您要做的下一件事是在您已经创建的 chart 对象上调用 addPlot 方法。在这里您为图表指定选项,包括它将是哪种类型的图表。Dojo 支持许多类型的图表。在本例中,您指定 Pie 作为类型。许多选项对于图表类型来说是特定的。例如,在这里您为扇形图指定半径,但其并不适用于其他图表类型。

下一步,您要在 chart 对象上调用 addSeries 方法。您将在其中传递来自 清单 1 的数据。然而,您需要轻微地处理一下此数据以便使其完美地用于 Dojo 的扇形图,这就是 makePieSeries 函数所作的事情。它获取浏览器中的数据并返回简单对象数组。每一个对象都有两种属性:ytexty 对象是值,而 text 是标签。在 makePieSeries 函数中的大多数代码都用于创建标签,此标签将显示浏览器的名称、有多少次点击以及总点击率。

返回到 init 函数,您要做的最后一件事是在图表上调用 render 函数。该函数实际上将促使 Dojo 在 web 页面上绘制图表。如前所述,一些绘图和系列选项根据图表的类型而不同。然而,addPlot/addSeries/render 模式是常见的。图 1 显示了该图表看起来将是什么样子。

图 1. 显示六月份浏览器统计信息的基本扇形图
显示六月份浏览器统计信息的基本扇形图

图 1 中的图表是 Dojo 扇形图的基本框架。唯一不默认的就是对于图表中的那些扇区您具有自定义标签。虽然它可能不是您见过的最漂亮的图表,但是它图形化地显示了商业智能数据,同时它采用了非常少的代码来生成。正如您将要看到的,使此图表更美观一点相当容易。


添加视觉效果

Dojo 使创建基本扇形图变得很容易,就像您在 图 1 中看到的一样。这可能与您希望展示给此图表的决策制定者的显示版本的不完全相同。幸运的是,Dojo 使添加一些视觉效果变得很容易。清单 3 显示了一些针对 清单 2 中代码的更新,将生成色彩更丰富的且交互性更强的扇形图。

清单 3. 色彩丰富的扇形图代码
dojo.require("dojox.charting.Chart2D");
dojo.require("dojox.charting.themes.Shrooms");
dojo.require("dojox.charting.action2d.MoveSlice");
dojo.require("dojox.charting.action2d.Tooltip");

function init(){
    pieChart = new dojox.charting.Chart2D("pie-chart");
    pieChart.addPlot("default", {
        type: "Pie",
        radius: 300,
        fontColor: "black",
        labelOffset : "-50"
    });
    var lastMonth = stats[stats.length -1];
    pieChart.addSeries("browsers", makePieSeries(lastMonth.data));
    var slice = 
          new dojox.charting.action2d.MoveSlice(pieChart,"default");
    var tip = new dojox.charting.action2d.Tooltip(pieChart,"default",{
        text : function(o) { 
            var run = o.run;
            var item = run.data[o.index];
            var label = item.text;
            var split = label.split(" : ");
            var browser = split[0];
            var percentage = split[1];
            var total = item.y;
            return browser + " : " + total + " (" + percentage + ")"; 
        }
    });
    pieChart.setTheme(dojox.charting.themes.Shrooms);
    pieChart.render();
}

清单 3 中首先应注意的是已经添加了几个新的 dojo.require 调用。您将看到代码的后半部分将引用这些对象中的每个对象。第一个被使用的是 MoveSlice 对象。这是一个简单的动画,当鼠标悬停在扇形图的某个扇区上时该扇区将弹出。随后使用的是 Tooltip 对象。这允许显示工具提示,即当鼠标悬停在扇形图的某个扇区上时显示的一些额外文本。将要显示的默认文本只是扇形图特定扇区的标签。如果您想显示其他信息,就像在这里的操作一样,您要提供一个名为 text 的函数。此函数产生将显示为工具提示的文本。在本例中,它将会显示类似于 FF35 : 5334121 (27.48%) 的提示。最后,最后添加的是针对您图表的 setTheme 方法的调用,传递 Dojo 提供的诸多颜色主题中的一个。此操作提供一些鲜明的色彩。图 2 显示了扇形图的更加丰富多彩的版本。

图 2. 特别的色彩扇形图
与图 1 相同的扇形图,但是带有颜色

现在更像了。正如您从 清单 3 中看到的,此主题被称为 Shrooms。您大概可以猜出原因。如果它对于您来说有点太亮的话,Dojo 提供了三十多个主题。您创建自己的主题也相当容易。此外,您不必使用主题。您可以为您扇形图的每一个扇区直接指定颜色。图 1图 2 两个图中所显示的图表仅仅显示了来自 清单 1 的六月份数据。让我们来看看您如何处理其他月份的数据。


处理多个系列

您可以很容易获取 清单 3 中的代码并使用它为来自 清单 1 的每一个月份的数据呈现图表。每一次,您将创建一个新的扇形图,这有一点低效。有一个更简洁和有效的方式来更改形成图表的数据。清单 4 显示了扇形图的修改版本,此版本允许用户选择将要显示的那个系列的数据。

清单 4. 带有数据切换控件的扇形图
function init(){
    // same as in Listing 3
    var chooser = dojo.byId("series-selector");
    var i = 0;
    var monthlyStats = null;
    var opt = null;
    for (i=0;i<stats.length;i++){
        monthlyStats = stats[i];
        opt = dojo.doc.createElement("option");
        opt.value = i;
        opt.appendChild(dojo.doc.createTextNode(monthlyStats.month));
        chooser.appendChild(opt);
    }
}
function aggregateResults(results){
    var aggResults = {};
    aggResults["IE"] = results.IE8 + results.IE7 + results.IE6;
    aggResults["FF"] = results.FF35 + results.FF3;
    aggResults["SAFARI"] = results.SAFARI + results.IPHONE;
    aggResults["CHROME"] = results.CHROME;
    aggResults["OPERA"] = results.OPERA;
    aggResults["OTHER"] = results.OTHER;
    return aggResults;
}
function selectSeries(){
    var selected = dojo.byId("series-selector").value;
    var aggBox = dojo.byId("aggBox").value;
    var series = stats[selected].data;
    if (aggBox){
        series = aggregateResults(series);
    }
    pieChart.updateSeries("browsers", makePieSeries(series));
    pieChart.render();
}
...
<div id="commandBar">
    <label for="series-selector">Choose Data:</label>
    <select name="series-selector" id="series-selector" 
           onchange="selectSeries()">
    </select>
    <label for="aggBox">Aggregate Data?</label>
    <input type="checkbox" id="aggBox" name="aggBox" 
          onchange="selectSeries()"/>
</div>

清单 4 中的代码将一些控件添加到图表中。首先有一个下拉框,显示来自 清单 1 的每一个数据系列。将在 init 函数中动态加载此数据。还有一个复选框,允许用户指定是否应该聚集数据,也就是说,是否把 Internet Explorer 的所有版本都添加到一起。

改变这些控件中的一个时,将调用 selectSeries 函数。此函数使用来自 HTML 控件的值以便确定应该使用哪个数据系列。然后,它会查看是否选择了聚集复选框,如果是,则它会对已选择的系列应用 aggregateResults 函数。最后,它通过在图表上调用 updateSeries 方法来更新图表,然后再次调用 render图 3 显示添加了新控件的扇形图。

图 3. 交互扇形图
彩色扇形图,底部具有用于选择要显示月份的控件,并且具有用于确定是否要汇集数据的复选框

现在,在数据用于创建扇形图以前,您可以切换数据系列,甚至应用汇集来转换数据。所有的主题和效果仍然适用,因为它仍然是同一图表。您只是切换该图表使用的数据。如果要查看在任何特定时间点什么浏览器对您的站点最重要,这是很有用的。然而,如果您想查看趋势,如什么浏览器在您的站点上用的更多或更少,扇形图就不是很有用了。让我们看看来自 Dojo 的可以用来查看趋势的不同类型图表。


多个系列的趋势分析

到目前为止您只看到过扇形图,因为它们为您正在使用的数据种类提供良好的可视性 — 显示给定月份中浏览器的相对份额。要显示趋势数据,也就是说,多个月内的数据,您需要一种不同类型的图表。线性图表似乎是一个显而易见的选择。然而,您将需要转换您的数据以使其更适合此种类型的图表。清单 5 显示了转换代码。

清单 5. 趋势分析的数据转换代码
var xStats = {};
function calcStats(){
    var i = 0;
    var mStats = null;
    var browser = "";
    var total = 0;
    for (i=0;i<stats.length;i++){
        mStats = (stats[i]).data;
        total = 0;
        for (browser in mStats){
            total += mStats[browser];
        }
        for (browser in mStats){
            if (!xStats[browser]){
                xStats[browser] = [];
            }
            xStats[browser].push(mStats[browser] / total);
        }
    }
}
dojo.addOnLoad(calcStats);

清单 5 中要做的第一件事是为存储新的数据创建名为 xStats 的全局变量。然后,定义一个名为 calcStats 的函数,此函数用来执行必要的转换。此函数在每个月的数据中迭代。它首先汇总该月的总浏览器点击数。然后再次在浏览器中迭代,计算该月浏览器的市场份额,并将其添加到 xStats。最后,xStats 将成为一个映射,其键是浏览器,而其值是浏览器市场份额的数组,所涉及的范围是该浏览从一月到六月的数据。这正是您需要的用于趋势分析的历史数据。最后,进行另一个调用,即 dojo.addOnLoad,以便在启动时执行此函数。现在您只需要将其转变为图表。清单 6 显示了您如何创建显示此数据的线性图表。

清单 6. 创建趋势数据的线性图表
dojo.require("dojox.charting.widget.Legend");
function makeTrends(){
    var chart = new dojox.charting.Chart2D("trends");
    chart.addPlot("default", {
        type: "Lines",
        markers : true,
        tension : "S",
        lines : true,
        labelOffset : -30,
        shadows : {dx:2, dy:2, dw:2}
    });
    chart.addAxis("x");
    chart.addAxis("y", {vertical:true});
    var browser = "";
    for (browser in xStats){
        chart.addSeries(browser, makeSeries(xStats[browser]));
    }
    chart.setTheme(dojox.charting.themes.Shrooms);
    chart.render();
    var legend =  new dojox.charting.widget.Legend({chart: chart}, 
          "legend");
}    
function makeSeries(data){
    var series = [];
    var i = 1;
    for (var key in data){
        series.push({x: i++, y :data[key]});
    }
    return series;        
}
dojo.addOnLoad(makeTrends);
<div id="trends" style="width: 800px; height: 800px;"></div>
<div id="legend"></div>

再一次通过添加新的 Dojo 依赖性开始您的代码。这一次它是 dojox.charting.widget.Legend 对象(稍后介绍此对象)。下一步,您要创建一个名为 makeTrends 的函数,此函数将创建新的图表。这类似于创建扇形图的代码。这一次您将拥有不同类型的 Lines。有几个专门用于线性图表的折线图选项,如标记(显示数据点)、张力(使直线弯曲)和阴影(给每条线一个下拉阴影)。请注意您还要添加两个轴,即创建所谓的 x 轴和 y 轴。然后,您要为每一个存储在 xStats 对象中的浏览器添加一个系列。对于每一个浏览器来说,您都要调用 makeSeries 函数。这基本上可将数据转换成 (x,y) 对,此处 x 是月份(1 = 一月、2 = 二月,等等),而 y 是浏览器的市场份额,如该月的百分比。返回到 makeTrends,调用 setTheme 方法,再次使用 Shrooms,然后调用 render。最后,您要使用之前提到的 Legend 对象来创建一个图例。图 4 显示了结果。

图 4. 数据趋势图表
在底部具有图例的显示趋势的彩色线图

通过此图表,您可以看到 Firefox® 3.5 和 Internet Explorer® 8 等随时间推移而增加了市场份额,而旧版本的 Internet Explorer 和 Firefox 正在逐渐减少。您可以使用此代码试验其他许多图表类型。例如,StackedLines 类型也非常有意思。您也可以合并之前显示的一些技术,如变更数据系列(例如,添加聚集视图等)。


结束语

本文已经向您显示了使用 Dojo 工具包创建互动图表的基础。您仅仅看到了 Dojo 支持的诸多图表类型中的两种。许多类型都具有多个独特的功能,这些功能可用于使图表真正具有视觉吸引力。看一下来自 Dojo 的文档以便查看您可以使用什么选项为您的报告应用程序创建最引人注目的图表。


下载

描述名字大小
本文源代码reports.zip3KB

参考资料

学习

获得产品和技术

  • 获得 Apache Hadoop。本文使用 0.20 版。
  • 获得 Java SDK。本文使用 JDK 1.6.0_17。
  • Google Libraries API:使用 Google 的 Ajax API 来下载 Dojo 到您的页面。
  • 查看建立在 Hadoop 之上的 PigHive 框架。
  • 下载 IBM 产品评估试用版软件,并开始使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Web development
ArticleID=710631
ArticleTitle=使用 Apache Hadoop 和 Dojo 降低商业智能成本,第 2 部分: 使用 Dojo 工具包创建引人注目的、交互的报告
publish-date=07062011