最近, 在开发公司的人进行了它的网站调查的状态, 这是由1899年的答卷人完成。结果在网上被分享了, 并且提出了武器的电话:网络数据的状态-要求分析!我用剑道界面来可视化这些数据的挑战: 结果在这里。
在这个博客文章中, 我将告诉你我是如何构建这个页面的。特别是, 我将集中在调查的两个部分, 我发现是最有趣的;一组意见陈述和一系列的 “是/否” 问题。这两种方法都是使用剑道 UI 构建的, 它为创建丰富的数据可视化提供了构建块。最后, 我想你会同意在外面画线是很有趣的。
可视化意见陈述
Web 调查的状态要求开发者对一系列声明发表意见。例如:
网络创新超过本土
受访者被要求就这些陈述发表意见, 从 (不 0
同意) 中评分 ( 10
同意)。
总共有18份, 每张都有11个不同的值 (0-10, 包含, 不包括空白分数)。考虑到许多语句的分数值的广度, 我觉得这 Grid
是最好的控件, 以便以有意义的方式显示这些数据。
首先, 我将这些意见列在以下数据结构中:
// opinionData.json
[
{
"text": "Web innovation is outpacing native",
"a0": 32,
"a1": 10,
"a2": 29,
"a3": 39,
"a4": 76,
"a5": 286,
"a6": 253,
"a7": 401,
"a8": 361,
"a9": 131,
"a10": 209,
"Blank": 72
},
// other opinions and vote totals here...
]
每个意见 ( text
) 都代表在一个数组中, 每个答案的总票数 ( a0
等于 0
或不同意, a10
等于 10
或同意)。之后, 我将此数据绑定到 Grid
具有元素 ID 的 a opinionGrid
:
$("#opinionGrid").kendoGrid({
columns: [
{ field: "text", title: "Opinion (0: Disagree, 10: Agree)" },
{ field: "a0", title: "0" },
{ field: "a1", title: "1" },
{ field: "a2", title: "2" },
{ field: "a3", title: "3" },
{ field: "a4", title: "4" },
{ field: "a5", title: "5" },
{ field: "a6", title: "6" },
{ field: "a7", title: "7" },
{ field: "a8", title: "8" },
{ field: "a9", title: "9" },
{ field: "a10", title: "10" }
],
dataSource: { data: opinionData }
});
这种配置生成了一个信息丰富而又乏味的前瞻性 Grid
:
Grid
提供了许多内置功能, 如分页、排序和筛选。启用排序是很容易的;只要将 sortable
属性设置为 true
, 用户就可以通过单击列标题来执行排序操作。按列排序 10
–表示与意见最一致–我们可以看到, 许多开发人员对在线广告最强烈的感觉是:
com.cn/wp-content/uploads/2018/09/pNTDud3-11.png “宽度 =” 825 “/>
不幸的是, 以这种方式对数据进行排序并不能说明整个事件。其他问题仍然存在。例如, 意见聚集在哪里?大多数开发商同意还是不同意意见?或者, 他们漠不关心吗?数据–正如这里所介绍的–并不具有太多的语义权重。
让我们添加一些颜色
好消息是, 我们可以通过添加颜色来表示单元格的值来改善这种情况。这是通过定义 Grid
。这是一个有用的扩展机制, Grid
它允许我们控制为每一行生成的标记。我们可以将此功能与色度结合使用. js根据每个单元格的值生成颜色的刻度:
import chroma from "chroma-js";
const voteBackgroundColor = chroma.scale(["fff","66f"]).domain([min,max]);
const voteColumnColor = function (votes) {
return voteBackgroundColor(votes).luminance() > 0.5 ?
"black" :
"white";
};
$("#opinionGrid").kendoGrid({
// ...
rowTemplate: function (e, data) {
var template = "<tr data-uid=\"" + kendo.guid() + "\">" +
"<td>" + e.text + "</td>" + // opinion column
"<td style=\"background-color:" + voteBackgroundColor(e.a0).hex() + ";" +
"color:" + voteColumnColor(e.a0) + "\">" + e.a0 + "</td>";
// output other columns (e.a1, e.a2, etc.)
template += "</tr>";
return template;
}
});
我用色度. js 定义一个 voteBackgroundColor
基于最小 ( min
) 和最大 max
值 () Grid
(在别处计算) 的颜色刻度函数。低值将由较浅的背景 (白色) 表示, 而高值则由较暗的背景 (蓝色) 表示。这些值是通过 API 生成 hex()
并通过样式应用的 background-color
。luminance()
色度的 API 用于 voteColumnColor
函数来确定 color
单元格的样式。明亮的颜色使用黑色, 而昏暗的颜色使用白色。这为更好的用户体验提供了一个对比度。
正如您所看到的, 添加颜色可以更深入地了解分数在特定观点中的聚集位置。快速浏览一下这些数据, 就会发现一些类似于 “我对 web 测试工具的状态感到满意” 和 “我不喜欢网络上的广告” 的观点的聚类。如果我们忽略数据分析并仔细观察, 在使用背景颜色的亮度来确定字体颜色后, 我们会更好地了解整体外观:
这是完成的, 而不影响的功能 Grid
。例如, 我们仍然可以对数据进行排序:
计算和显示平均值
让我们进一步通过添加列来显示每行的平均分数。这将使我们能够确定最/最不支持的意见。如果我在函数内部计算这些值 rowTemplate
, Grid
就无法对它们进行排序。这是因为操作 (如排序) 是通过绑定进行的 DataSource
; 而不是它所绑定的控件 (我Grid
).因此, 为了保留排序能力 Grid
, 我必须在绑定数据源中保留平均分数:
// scores are 0-10 (inclusive)
function calculateAverages(opinions) {
for (var i = 0; i < opinions.length; i++) {
var avg = 0;
for (var j = 0; j < 11; j++) {
avg += j * opinions[i]["a" + j];
}
avg = avg / total;
opinions[i].avg = avg;
}
return opinions;
}
一旦将平均分数添加到绑定数据源, 我们就可以 Grid
像这样显示它:
$("#opinionGrid").kendoGrid({
columns: [
{ field: "avg", title: "Avg" }
// other columns here...
]
});
下面是 Grid
按平均列排序的:
哇。开发者真的不喜欢网络上的广告。他们对带菌者患者的未来也持乐观态度, 并认为网络正在为最终用户改善。相反, 他们似乎不同意的意见, “桌面网站通常是缓慢和缓慢的” 和 “我对网络测试工具的状态感到满意”。
我们可以添加一些冲床, Grid
通过使用我们以前使用的方法, 根据其值对每个单元格着色。在这里, 我们将定义另一个 fAvg
基于最小 ( minAvg
) 和最大 () 平均分数的颜色缩放函数 minAvg
:
const fAvg = chroma.scale(["fff","999"]).domain([minAvg,minAvg]);
$("#opinionGrid").kendoGrid({
// ...
rowTemplate: function (e, data) {
// ...
var avgColumnColor = fAvg(e.avg).luminance() > 0.5 ? "black" : "white";
template += "<td style=\"background-color:" + fAvg(e.avg).hex() + ";color:" + avgColumnColor + "\">" + e.a0 + "</td>";
// ...
}
});
以下是 Grid
与此更改:
数据可视化功能支持 SVG 和 HTML5 <canvas>
元素。
让我们添加迷你图更多的活力
a Sparkline
是一个小图表, 您可以将其嵌入到其他控件中, 如 Grid
。它是超级经济的屏幕上的房地产, 因为它包了很多信息到一个狭小的空间。
让我们添加另一个列以显示 Sparkline
每行的 a。我们必须得到一些创造性的做到这一点, 因为 Grid
有一个 rowTemplate
定义。我将创建一个函数, 它输出以 Sparkline
声明式方式 (通过属性) 创建所需的标记 data-*
:
function getSparkline(data) {
return "<td><div class=\"sparkline\"" data-chart-area=\"{background:'transparent'}\" data-role=\"sparkline\" data-series=\"[{type:'column',data:[" + data + "]}]\" data-series-defaults=\"{gap:0.1}\" data-theme=\"material\"></div></td>";
}
我将为要为其初始化的事件添加一个处理程序, dataBound
Grid
Sparkline
并生成 Sparkline
通过 rowTemplate
函数:
$("#opinionGrid").kendoGrid({
// ...
columns: [
// other columns here...
{ } // add a column for the sparkline
],
dataBound: function (e) {
kendo.bind(".sparkline");
}
rowTemplate: function (e, data) {
// ...
template += getSparkline(opinions);
}
});
结果如下:
下面是一个500% 缩放级别的示例:
Sparkline
也可以向 HTML5 <canvas>
元素呈现。
用户交互
默认情况下, 当用户悬停在它们上时, 会突出显示行 Grid
。由于我们已经在每个单元格中应用了背景色的样式, 因此这会覆盖默认行为。例如, 如果我们将鼠标悬停在一行上, 则该行的样式将被我们前面在函数中添加的部分重写 rowTemplate
:
让我们用一个突出显示每一行的样式规则来修正此行为:
#opinionGrid tbody > tr:hover > td {
background-color: #ffa !important;
color: black !important;
}
我不是一个使用的爱好者, !important
但在这种情况下, 必须重写以前应用的颜色 styoles。通过此更改, 当鼠标悬停在它们上时, 将 highlghted 各个行:
可视化是/否问题
调查的另一部分要求开发人员对一系列问题提供 “是/否” 答案。例如:
您的团队/项目支持 IE 10 和下?
总共有9个问题被回答 (不包括空白分数) yes
或 no
与相关的总计。可视化此数据的适当方法是使用 Grid
与 a 的组合 Sparkline
来创建 “是/否” 图表:
我很惊讶地发现, 没有多少开发者在他们的 web 应用程序中使用WebP 格式的图像。我推测现在有更多的开发者使用这种格式。我想新的图像格式可能需要很多时间才能被采纳。
用于创建此可视化的配置相当简单:
$("#yesNoGrid").kendoGrid({
columns: [
{ field: "Question" },
{ field: "No", headerAttributes: { style: "text-align:right;" } },
{ field: "Yes" }
],
dataBound: function (e) {
kendo.bind(".yesNoSparkline");
},
dataSource: { data: yesNoData, sort: { field: "No", dir: "desc" } },
rowTemplate: function (e, data) {
return "<tr data-uid=\"" + kendo.guid() + "\">" +
"<td>" + e.Question + "</td>" +
getYesNoColumn("No", e.No, "#f66") +
getYesNoColumn("Yes", e.Yes, "#00b312") +
"</tr>";
},
scrollable: false,
sortable: true
});
在这里, 我们使用的技术是 Grid
通过定义函数来创建上一节的 rowTemplate
。这将使用调用的函数作为 getYesNoColumn
帮助函数来生成 Sparkline
:
function getYesNoColumn(vote, voteCount, color) {
var votePosition = voteCount > 400 ? "insideEnd" : "outsideEnd";
var voteLabelColor = voteCount > 400 ? "#fff" : "#000";
var reverse = vote == "No" ? ",reverse:true" : "";
var textAlignment = vote == "No" ? " style=\"text-align:right;\"" : "";
return "<td" + textAlignment + "><div class=\"yesNoSparkline\" data-chart-area=\"{background:'transparent',margin:0}\" data-value-axis=\"{max:1899" + reverse + "}\" data-role=\"sparkline\" data-plot-area=\"{background:'transparent',margin:0}\" data-series=\"[{color:'" + color + "',data:[" + voteCount + "],labels:{color:'" + voteLabelColor + "',position:'" + votePosition + "',visible:true},stack:false,type:'bar'}]\" data-series-defaults=\"{gap:0,margin:0,spacing:0}\" data-theme=\"flat\" data-tooltip=\"{visible:false,shared:false}\"></div></td>";
}
Sparkline
控件中生成的每个小部件的标签的位置。Grid
cheeli/wp-内容/上传/2018/09/g6WF2Zc-5. png
去找点乐子吧!
剑道 UI 为创建丰富的数据可视化提供了构建块。然而, 这并不能限制你的创造力。事实上, 有时在线条外画是很有趣的。正如您在博客文章中看到的那样, 有很多有趣的方法可以用剑道 UI 来可视化数据。
你可以在 StackBlitz 上查看我用剑道 UI 构建的完整的调查数据可视化: SOTW 调查 2018。同时, 不要害怕有一些乐趣与使用剑道用户界面为您的数据可视化项目!