BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

使用Bootstrap与ShieldUI创建销售业绩仪表板

| 作者 David Johnson 关注 0 他的粉丝 ,译者 邵思华 关注 3 他的粉丝 发布于 2015年1月28日. 估计阅读时间: 32 分钟 | Google、Facebook、Pinterest、阿里、腾讯 等顶尖技术团队的上百个可供参考的架构实例!

今天,让我们来创建一个基于Bootstrap框架的仪表板(dashboard)应用程序。

Bootstrap是一套非常流行的前端框架,它旨在帮助开发者解决开发过程中的一些主要问题,例如元素的定位、应用的响应式能力以及在多种设备上进行输出。这个仪表板应用程序的元素包括一系列的可视化图形,它们各自代表了各种关键性能指标,例如预算、访问量及其它一些关键指标。

如果你想要实现的应用不仅仅能够简单地表现数据,还能以一种具有竞争力及优秀的表现形式进行呈现,则需要通过以下两个步骤进行实现。

首先,我们需要以小部件(widget)的形式呈现所有底层的数据,并提供一种额外的交互层次,例如提示(tooktip)、选项(selection)及鼠标放置(hover)效果。某些数据还可以使用经过编码的QR码形式进行呈现,它所适用的场合包括:展现一个很长的超链接,或是对某个特定的条目需要显示额外的细节信息。

可以使用ShieldUI这套web开发框架实现这一任务,这套框架提供了我们所需的各种小部件。我们将使用这套框架中的jQuery小部件,例如图表(chart)、网格(grid)、QR码以及评分部件,这些部件提供了非常优秀的客户端性能以及影响式的能力。

其次,我们需要确保将仪表板中的所有元素都呈现在页面中相互分离的各个区域。不仅如此,我们还需要确保所有这些区域在定位上都是相连的,并且在任何设备上都能够良好地进行呈现。一般来说,实现这个任务是非常复杂的。但幸运的是,Bootstrap框架能够大大地简化这一任务,只需正确地使用某些CSS类便可实现了。

你可以在这里找到该示例的完整代码下载。完成的应用程序界面请见下图:

(单击图片以放大)

应用程序结构

一个完整的仪表板或许会包括无数种小部件与页面布局的组合,我在这里选择的是最常见的组合。从布局的角度来说,该应用的页面共分为五个响应式的面板,这些面板的定位是由Bootstrap的布局系统所决定的。在较小的屏幕尺寸上,每个区域都会充分占据所有可用的空间。

该应用中所用到的小部件包括jQuery QR码、jQuery评分控件、两种不同布局的图形控件、一个jQuery图表插件,一个环形的进度条,以及一个网格控件。在开发的角度上,我创建了一个简单的html文件,将所有必需的代码都放在该文件中。

必需的资源文件

该应用程序的head区域引用了所需的全部资源文件,包括Bootstrap的CDN资源,它会负责加载所有必需的CSS类,以及jQuery和ShieldUI的脚本文件引用。Head区域的最后是一段JSON文件的引用,它包含了网格组件所需的原始数据。

以下是完整的head区域的内容:

<head>
    <title>Bootstrap Dashboard</title>

    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href=" />
    <link rel="stylesheet" type="text/css" href=" />
    <link rel="stylesheet" type="text/css" href=" />
    <script type="text/javascript" src="></script>
    <script type="text/javascript" src="></script>
    <script src="gridData.js"></script>
</head>

当所有的资源文件都准备好之后,我们就可以着手打造该页面了。我会依次讲解该页面中所有面板的功能。

用户个人信息

该区域将使用一个标准的Bootstrap面板以呈现基本的用户信息细节:包括用户/雇员名称、所属部门以及职位。在该面板的注脚部分包含了一个QR码,其中包含了额外的用户信息,也可对它进行扩展,以经过编码的URL形式表示完整的用户信息或其它相关数据的对应页面。

这块区域是由以下代码所生成的:

<div class="col-sm-6 col-lg-3">
                <div class="panel panel-primary">
                    <div class="panel-heading">
                        <h4 class="text-center">User Profile<span class="glyphicon glyphicon-user 
pull-right"></span></h4>
                    </div>
                    <div class="panel-body text-center">
                        <p class="lead">
                            <strong>Mike Smith</strong>
                        </p>
                    </div>
                    <ul class="list-group list-group-flush">
                        <li class="list-group-item liitem"><strong>Position:</strong>
                            <span class="pull-right">Developer</span>
                        </li>
                        <li class="list-group-item liitem"><strong>Company:</strong>
                            <span class="pull-right">EasyTech</span>
                        </li>
                        <li class="list-group-item liitem"><strong>Department:</strong>
                            <span class="pull-right">Dataviz</span>
                        </li>
                        <li class="list-group-item liitem"><strong>Project Duration:</strong>
                            <span class="pull-right">12 months</span>
                        </li>
                    </ul>
                    <div class="panel-footer">
                        <div class="row">
                            <div class="col-xs-4 col-sm-3 col-md-4 col-lg-2">
                            </div>
                            <div class="col-xs-2 col-sm-4 col-md-4 col-lg-4" id="qr1">
                            </div>
                            <div class="col-xs-6 col-sm-5 col-md-4 col-lg-6">
                            </div>
                        </div>
                    </div>
                </div>
            </div>

这个面板的注脚部分包含了一个id为“qr1”的div,在页面进行加载时,QR码会在该div中进行初始化。其它所有html元素都应用了标准的Bootstrap类,这些类会负责处理与定位和响应式编码,这就为开发者解决了大量的问题与开发过程中可能遇到的挑战。

用户细节

页面中的这部分内容与前文所述的用户信息非常相似,但它所列举的是用户的个人技能信息。每一项个人技能的右方是一个评分组件,描述了每一项内容的个人专业程度。将鼠标移至该评分元素上,并单击选择,就可以对每一项评分的值进行变更。

与第一个面板相同,注脚部分同样包含了一个QR码,包含了经过编码的额外信息,例如某个独立的页面或Url。

这一区域是由以下代码所创建的:

<div class="panel panel-primary">
                    <div class="panel-heading">
                        <h4 class="text-center">Skills<span class="glyphicon glyphicon-saved
 pull-right"></span></h4>
                    </div>
                    <div class="panel-body text-center">
                        <p class="lead">
                            <strong>Technology Overview</strong>
                        </p>
                    </div>
                    <ul class="list-group list-group-flush">
                        <li class="list-group-item liitem">
                            <div class="skillLineDefault">
                                <div class="skill pull-left text-center">HTML5</div>
                                <div class="rating" id="rate1"></div>
                            </div>
                        </li>
                        <li class="list-group-item liitem">
                            <div class="skillLineDefault">
                                <div class="skill pull-left text-center">CSS</div>
                                <div class="rating" id="rate2"></div>
                            </div>
                        </li>
                        <li class="list-group-item liitem">
                            <div class="skillLineDefault">
                                <div class="skill pull-left text-center">jQuery</div>
                                <div class="rating" id="rate3"></div>
                            </div>
                        </li>
                        <li class="list-group-item liitem">
                            <div class="skillLineDefault">
                                <div class="skill pull-left text-center">C#</div>
                                <div class="rating" id="rate4"></div>
                            </div>
                        </li>
                    </ul>
                    <div class="panel-footer">
                        <div class="row">
                            <div class="col-xs-4 col-sm-3 col-md-4 col-lg-2">
                            </div>
                            <div class="col-xs-2 col-sm-4 col-md-4 col-lg-4" id="qr2">
                            </div>
                            <div class="col-xs-6 col-sm-5 col-md-4 col-lg-6">
                            </div>
                        </div>
                    </div>
                </div>

包括QR码与评分控件在内的所有小部件元素,都是由一个包含了唯一的ID的简单的div元素进行展现的。页面在运行时会通过该ID创建一个相应的小部件。

季度业绩区域

仪表板中的这一区域将通过一个jQuery图表插件展现该季度的数据。这段示例中包括了两个序列的数据,可用以绘制个人、员工或公司数据。可以对序列的数量进行调整,以适应对更多数据展现的需要。不过应尽可能将序列的数量控制在最小范围内,以确保良好的阅读体验。

这一区域是由以下代码所创建的:

<div class="col-sm-12 col-md-12 col-lg-6">
                <div class="panel panel-primary" style="height: 491px;">
                    <div class="panel-heading">
                        <h4 class="text-center">Quarterly Performance<span 
class="glyphicon glyphicon-screenshot pull-right"></span></h4>
                    </div>
                    <div id="chart1">
                    </div>
                </div>
            </div>

这个面板中仅包含了两个区域的内容,因此对应的html代码也十分简单易懂。图表小部件在运行时加载数据,它的整体结构是由以下JavaScript代码专用所定义的:

function initializeChart1() {
            var data1 = getRandomArray(20, 1, 50);
            var data2 = getRandomArray(20, 20, 70);
            $("#chart1").shieldChart({
                theme: "light",
                exportOptions: {
                    image: false,
                    print: false
                },
                primaryHeader: {
                    text: "Performance Data"
                },
                tooltipSettings: {
                    axisMarkers: {
                        enabled: true,
                        mode: 'x',
                        width: 2,
                        zIndex: 3,
                        drawColor: "white"
                    }
                },
                dataSeries: [
                    {
                        seriesType: 'bar',
                        collectionAlias: 'Achieved',
                        data: data1
                    },
                    {
                        seriesType: 'line',
                        collectionAlias: 'Target',
                        data: data2
                    }
                ]
            });
        }

出于本文的篇幅考虑,这段示例使用的是随机数据,但也可对其进行扩展,从其它任何渠道获取数据。代码中的dataSeries属性用于描述该图表中所呈现的两种类型的序列,即线状图与饼图。

整体业绩区域

该区域也是一个包含了可视化数据的面板,其中使用了一个进度条控件,可表现业绩数据,或是某个任务或目标的完成进度百分比。它为用户提供了一种查看某个目标能否及时完成的快速的可视化参考。

通过对这段代码进行简单的扩展,可以使用不同的颜色集,例如以绿色表示目标达成,或是以红色表示进度落后。

全公司业绩区域

这个区域的代码相比其它几个区域有所增加,因此可以参考本文所附带的示例,以获取完整的内容。从结构的角度来说,该面板区域共包含了三个子区域。

  • 文本子区域可以让用户快速地了解该面板对应了哪种可视化的数据,在本例中它表示的是预算的趋势。
  • 第二个子区域中包含了三个图表及简单的布局,即以数据曲线所表现的趋势数据。
  • 最后一个子区域中是一个高度可见的文本区域,它直接反应了每一行所对应的数值。

完整的公司数据区域

该区域包含了一个标准的网格表,以多个行的形式表现数据。可以在该网格中展现公司数据,或用以展现某个公司的全体员工列表。该组件内置了对排序及分页的支持。

(单击图片以放大)

该区域所对应的html部分代码如下所示:

<div class="row">
            <div class="col-sm-12 col-md-12 col-lg-12">
                <div class="panel panel-primary" style="height: 472px; min-width: 597px;">
                    <div class="panel-heading">
                        <h4 class="text-center">Full Company Data<span class="glyphicon 
glyphicon-eye-open pull-right"></span></h4>
                    </div>
                    <div id="grid1" style="max-height: 393px;">
                    </div>
                </div>
            </div>
        </div>

这段代码包含了面板的声明,包括header与body。除此之外,其中还包含了一个id为“grid1”的div,它将在运行时呈现整个表格的布局。

初始化小部件

每个小部件都与一个JavaScript函数所对应,后者会负责进行初始化工作。举例来说,前文中所提到的网格小部件是由以下函数进行初始化的:

function initializeGrid1() {
            $("#grid1").shieldGrid({
                dataSource: {
                    data: gridData
                },
                sorting: {
                    multiple: false
                },
                paging: {
                    pageSize: 8,
                    pageLinksCount: 10
                },
                selection: {
                    type: "row",
                    multiple: true,
                    toggle: false
                },
                columns: [
                    { field: "id", title: "ID" },
                    { field: "name", title: "Person Name" },
                    { field: "company", title: "Company Name" },
                    { field: "email", title: "Email Address" }
                ]
            });
        }

为了本文的简洁性,我没有列举出完整的代码,但逻辑是相同的:即每个这样的函数都将对一个独立的小部件进行初始化,而每个小部件会进一步进行可视化与交互的相关操作。

至此,页面的装配工作以及大部分的元素已准备就绪。欢迎读者下载示例的代码,在本机进行尝试,或进一步探索每个区域、元素或小部件的功能。

关于作者

David Johnson来自于英国伦敦,他是一位37岁的开发者。过去的15年间,他主要工作于web技术的领域,而近10年间,他主要专注于ASP.NET和MVC平台。David作为一名外包开发者参与过许多项目,最近的职位是在ShieldUI担任首席开发者。

 

查看英文原文:Article: Creating a Sales Dashboard with Bootstrap and ShieldUI

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT