最近, 在开发公司的进行了它的网站调查的状态, 这是由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 –表示与意见最一致–我们可以看到, 许多开发人员对在线广告最强烈的感觉是:

Image title不幸的是, 以这种方式对数据进行排序并不能说明整个事件。其他问题仍然存在。例如, 意见聚集在哪里?大多数开发商同意还是不同意意见?或者, 他们漠不关心吗?数据–正如这里所介绍的–并不具有太多的语义权重。

让我们添加一些颜色

好消息是, 我们可以通过添加颜色来表示单元格的值来改善这种情况。这是通过定义 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-colorluminance()色度的 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);
  }
});

结果如下:

Sparkline也可以向 HTML5 <canvas> 元素呈现。

用户交互

默认情况下, 当用户悬停在它们上时, 会突出显示行 Grid 。由于我们已经在每个单元格中应用了背景色的样式, 因此这会覆盖默认行为。例如, 如果我们将鼠标悬停在一行上, 则该行的样式将被我们前面在函数中添加的部分重写 rowTemplate :

让我们用一个突出显示每一行的样式规则来修正此行为:

#opinionGrid tbody > tr:hover > td {
  background-color: #ffa !important;
  color: black !important;
}

我不是一个使用的爱好者, !important 但在这种情况下, 必须重写以前应用的颜色 styoles。通过此更改, 当鼠标悬停在它们上时, 将 highlghted 各个行:

可视化是/否问题

调查的另一部分要求开发人员对一系列问题提供 “是/否” 答案。例如:

您的团队/项目支持 IE 10 和下?

总共有9个问题被回答 (不包括空白分数) yesno 与相关的总计。可视化此数据的适当方法是使用 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控件中生成的每个小部件的标签的位置。Gridcheeli/wp-内容/上传/2018/09/g6WF2Zc-5. png

去找点乐子吧!

剑道 UI 为创建丰富的数据可视化提供了构建块。然而, 这并不能限制你的创造力。事实上, 有时在线条外画是很有趣的。正如您在博客文章中看到的那样, 有很多有趣的方法可以用剑道 UI 来可视化数据。

你可以在 StackBlitz 上查看我用剑道 UI 构建的完整的调查数据可视化: SOTW 调查 2018。同时, 不要害怕有一些乐趣与使用剑道用户界面为您的数据可视化项目!

Comments are closed.