使用普通Javascript创建交互式图表(第一部分)
交互式图表与简单的Javascript
介绍
今天的浏览器让我们以前所未有的方式连接信息。信息图表就是这样一个领域。作为象形图,它是一个出色的可视化工具。作为一个交互式网页,您只需进行一些编码即可实现新的参与度。
许多开源库渲染出奇妙的图表。我们的最爱是D3和vis.js. 但是,还有一些时候我们需要公共图书馆无法提供的功能。
目的
让我们用简单的Javascript构建一个交互式信息图。
案例分析
Google Cloud Platform(GCP)就像是Web开发人员的糖果店。它的产品类别超过了手指可以计数,并且每个互连以不同的方式解决复杂问题。
GCP“组织结构图”。官方消息来源:Google Cloud Platform
如果我们利用现代浏览器的强大功能来展示GCP产品的优势,那么UI将如何呈现?是否可以使用基本的Javascript技术来产生非凡的结果?
设计方法
我们的设计方法基于使用一致且持久的用户界面(UI)来讲述引人入胜的故事的想法。让我们重新思考两个方面的设计:
- 信息架构。我们可以将信息视为连续路径,而不是通过重复页面加载缝合的曲线拼图块吗?
- 用户界面(UI)。我们能否通过互动且一致的用户界面呈现信息?
UI概念:镜子
- 简洁。我们希望使用尽可能少的代码创建可自定义的UI。
- 简单。我们希望使用开箱即用的浏览器功能,而不是第三方库。这意味着只使用Plain Javascript。
- 可重用性。我们希望将视图与模型分开,以便更容易使我们的项目适应其他用例。
入门 - 基本构建块
让我们将节点和链接的概念作为我们设计工作流程的基本构建块。
节点是起点和终点。例如,公共汽车站可以称为节点。从一个节点到另一个节点的总线路径可以称为链路。一组相关的节点和链接可以称为一个分支。
基本构建块:每个节点描述一组唯一关系
节点元素。我们可以使用HTML元素和唯一ID来描述节点。例如,node11
将是分支#1的节点#1。类似地,node12
将是分支#1的节点#2。在上图中,它将是圆“1”和“2”。总线路径#1(即分支#1)将连接圆圈“1”和“2”以及其他圆圈(即2a,3,3a,3b)。
让我们使用该style
属性来描述每个元素的独特位置,形状和行为。您可以使用任何HTML,CSS,图标或图像来表示节点或链接。我们视频中的圆形节点只是带有CSS的div标签border-radius
。
<div id=”node11" style=”…”>1–1 Occupation Name</div>
<div id=”node12" style=”…”>1–2 Occupation Name</div>
链接元素。链接连接节点。例如,link1112
连接node11
和node12
。
<div style=”...” id=”link1112"></div>
提示:使用图像叠加层来指导HTML元素的CSS定位。
抛开概念 - 互动如何在网页上运作
我们讨论过的节点和链接本质上是浏览器运行时的DOM元素。DOM或文档对象模型是一种树状数据结构,用于表示HTML元素并将内容映射到物理显示。
相反,我们也可以通过操纵DOM与任何显示元素进行交互。在我们的项目中,我们希望这些节点和链接响应特定的用户操作,例如mouseover
事件。
document.addEventListener( "mouseover", myCustomFunction );
-
mouseover
检测鼠标光标悬停在特定DOM文档(如按钮)上。 - 一旦检测到,它将调用
myCustomFunction
做某事(例如弹出动画序列或从数据库中检索信息)。
我们将使用此Javascript API来检测用户操作并触发一系列功能来创建交互式网页。
创建工作流快捷方式
让我们团结节点和链路元素,其event listeners
内的loop
两个步骤:
第一步。分配模型(数据)。
将HTML元素的唯一id
值存储为item[]
数组。
var item = [
‘11’,’12',’1112',
‘21’,’22',’2122',
...
];
item []数组中的每个值将对应于每个节点或链接的唯一id值(例如,11
指代node11
; 1112
指代link1112
。)。您可以将item []视为主注册表。
接下来设置legend[]
举行an array of objects
。每个对象都是一个与特定用户操作相对应的数据集。
var legend = {
'item11' : { "node" : ['11'], "links" : [] },
'item12' : { "node" : ['11','12'], "links" : ['1112'], },
...
}
- 当鼠标光标悬停时
node11
,该对象item11
将调用node11
CSS目标。 - 同样,当光标悬停node12,对象
item12
调用node11
,node12
以及link1112
对CSS的定位。 -
item
只是一个前缀标签。使用您的命名约定。
我们花点时间考虑上述模式的含义。我们不仅创建了一个存储内容的系统,还创建了一个图形关系来描述数据连接。
我们减少了大量的代码; 加快设计工作流程; 并将视图与模型(数据)分开。让我们继续构建视图引擎。
提示:对于动态内容管理,请考虑将数据集编码为JSON并通过数据库访问它们。此外,使用任何工具编辑数据集和HTML布局。
第二步。遍历每个HTML元素以编程方式关联事件侦听器。
while (item[i]) {
itemElement[i] = "node".concat(item[i]);
itemElementName[i] = document.getElementById( itemElement[i] );
itemElementName[i].addEventListener( "mouseover", mouseOver );
itemElementName[i].addEventListener( "mouseout", mouseOut );
...
i++;
}
-
while
迭代注册的每个DOM元素的id值item[]
。 -
“item”.concat(item[i])
重新附加您可能拥有的任何自定义前缀(即“节点”)以匹配实际的id值。 -
itemElementName[i] = document.getElementById( item[i] )
构建一个DOM引用数组。 - “
mouseover
”和“mouseout
”将每个DOM元素绑定到用户操作。
提示#1:移动设备和触摸设备有自己的一组事件监听器,如*touchstart*
和*touchmove*
。使用它们来创建响应式设计。
提示#2:在触摸或滚轮事件监听器上使用“被动”参数来提高浏览器性能,如下所示:
document.addEventListener('touchstart', onTouchStart, {passive: true});
使用CSS自定义交互行为
我们可以创建自定义函数mouseOver
并mouseOut
应用CSS效果:
function mouseOver(event) {
for (var i in legend[this.id]["node"]) {
var currKey = "node".concat(legend[this.id]["node"][i]);
document.getElementById(currKey).style.background = "grey";
...
}
for (var i in legend[this.id]["link"]) {
var currKey = "link".concat(legend[this.id]["link"][i]);
document.getElementById(currKey).style.border = "1px solid
#000";
...
}
}
- 使用事件侦听
mouseover
器将DOM元素绑定到自定义函数mouseOver
。此函数接受event
参数(由浏览器提供)以提供活动this.id
值。 -
legend[this.id][“node”]
标识用于应用CSS定位的数据集。 -
*for*
循环通过集合legend[]
。
在我们的示例中,该mouseOver
函数将目标节点的背景颜色变为灰色。
在link
元素上使用相同的想法。在我们的示例中,links1112
当鼠标指针悬停在node12
(node11和node12也变为灰色)时,我们将颜色从灰色变为纯黑色。
接下来,只要光标退出当前DOM元素,就“重置”CSS行为(参见粗体)。
function mouseOut() {
for (var i in legend[this.id]["node"]) {
var currKey = "node".concat(legend[this.id]["node"][i]);
document.getElementById(currKey).style.background = "unset";
...
}
for (var i in legend[this.id]["link"]) {
...
}
}
使用SVG无限缩放
我们的GCP信息图表广泛使用SVG来支持高清分辨率的缩放功能,这将在我们讨论的下一部分中实现。
要更改HTML / CSS circle 1
,或node11
,成六角形状SVG,则只需将一个HTML容器内的SVG内容(见粗体)。
<div id=”node11" style=”display:flex; align-items:center;">
<svg>
<path d="...some paths"/>
</svg>
<div style="align-items:center; width:100%;">
My Text Label
</div>
</div>
-
id=”node11"
引用相同的节点。它现在包含SVG数据,而不是呈现HTML圆形。 -
display:flex
并align-items:center
使用现在所有主流浏览器都支持的Flexbox来自动调整我们的SVG和文本内容。 -
<svg>...</svg>
包含描述我们的zoomable图标的SVG数据。访问官方GCP图标库以下载完整的图标包。
填充内容
我们将SVG添加到模型中。让我们看看到目前为止GCP内容的样本布局是如何看的。
图形关系以及与SVG内容的交互
- 使用
scale3d
效果创建有影响力的突出显示效果。 - 使用
dashed
说明不同的关系。
下一步
我们设计了一个模式和一个视图引擎作为我们设计工作流程的基础。
在下一部分中,我们将向UI添加导航功能。
边注
这个故事是一个由Javascript创建交互式信息图表的5部分系列。我们精心挑选了重要的内容,以便您可以快速找到基本部件并在项目中进行调整。它确实有助于您掌握一些CSS和HTML知识。隐藏了不相关的代码块。
所有视频插图均通过Chrome浏览器截屏。虽然该演示基于GCP,但您可以在组织结构图,生态系统,地铁地图,流程图,进度树,网络拓扑和任何图表图中找到应用程序。
非常感谢Chuck Erickson和Google团队提供了精彩的GCP解决方案图标和图表包。
转:https://medium.com/hackernoon/how-to-build-an-interactive-infographic-from-scratch-94128678c83b