【D3.js in Action 3 精译_028】3.4 小节 DIY 实战:使用 Observable 在线绘制 D3 条形图

当前内容所在位置(可进入专栏查看其他译好的章节内容)

  • 第一部分 D3.js 基础知识
    • 第一章 D3.js 简介(已完结)
      • 1.1 何为 D3.js?
      • 1.2 D3 生态系统——入门须知
      • 1.3 数据可视化最佳实践(上)
      • 1.3 数据可视化最佳实践(下)
      • 1.4 本章小结
    • 第二章 DOM 的操作方法(已完结)
      • 2.1 第一个 D3 可视化图表
      • 2.2 环境准备
      • 2.3 用 D3 选中页面元素
      • 2.4 向选择集添加元素
      • 2.5 用 D3 设置与修改元素属性
      • 2.6 用 D3 设置与修改元素样式
      • 2.7 本章小结
    • 第三章 数据的处理 ✔️
      • 3.1 理解数据(已完结)
      • 3.2 准备数据(已完结)
      • 3.3 将数据绑定到 DOM 元素(已完结)
        • 3.3.1 利用数据给 DOM 属性动态赋值
      • 【3.4 让数据适应屏幕】 ✔️
        • 3.4.1 比例尺简介(上篇)
        • 3.4.2 线性比例尺(中篇)
          • 3.4.2.1 基于 Mocha 测试 D3 线性比例尺(DIY 实战)
          • 3.4.2.2 使用 Observable 在线绘制 D3 条形图(DIY 实战) ✔️
        • 3.4.3 分段比例尺(下篇)
      • 3.5 加注图表标签(待翻译 ⏳)
      • 3.6 本章小结

文章目录

  • 3.4.2.2 使用 Observable 在线绘制 D3 条形图(DIY实战)
    • 1 需求描述
    • 2 操作步骤
      • 2.1 加载数据
      • 2.2 数据绑定
      • 2.3 调整比例
    • 3 小结 & 复盘

《D3.js in Action》全新第三版封面

《D3.js in Action》全新第三版封面

3.4.2.2 使用 Observable 在线绘制 D3 条形图(DIY实战)

写在前面

作为本书第三章的有益补充,一名合格的数据可视化从业者应该时刻关注业界最新前沿趋势、主流观点、最佳实践等等。这当中就必然包括 Observable 网站资源的合理利用。前面第一章介绍 Observable 笔记本功能(Notebooks)时,由于作者感觉偏离了本书重点,于是草草几句就结束了。今天就给大家打个样,去探探这个由 D3.js 创始人打造的 Observable 平台的深浅。

1 需求描述

根据目前的专栏进度,第三章的示例条形图除了数据标签还没实现,其他的部件基本都实现了。这次索性就把 D3 工作流那几个节点(如下图所示)从头到尾在 Observable 上实现一遍。

图 1 要同步在 Observable 实现一遍的 D3 数据工作流关键节点

【图 1 要同步在 Observable 实现一遍的 D3 数据工作流关键节点】

2 操作步骤

首先登录 Observable 平台:https://observablehq.com/。用邮箱注册一个帐户或者直接关联 GitHub 帐号即可。登录成功后,从个人主页右上方新建的一个笔记本,如图 2 所示:

图 2 新建一个 Observable 笔记

【图 2 新建一个 Observable 笔记】

在弹出窗口中为这个新笔记指定一个工作空间(Workspace),就相当于一个顶层文件夹。通常默认会选中一个,也可以手动指定。右边的模板就选默认的空白模板(Blank)即可,如图 3 所示:

图 3 为新笔记文件指定一个工作空间

【图 3 为新笔记文件指定一个工作空间】

点击 Create notebook 按钮,就正式进入 Observable 记事本的编辑页面了。此时会看到一个默认的 Markdown 格式的单元格,如图 4 所示:

图 4 进入 Observable 记事本编辑页看到的第一个单元格

【图 4 进入 Observable 记事本编辑页看到的第一个单元格】

那就用 Markdown 来一个华丽的标题吧,输入:# Ch3.4.3.1 DIY: Demo Bar Chart,然后按 Shift + Enter 快速执行,就有了下面的标题:

图 5 使用 Markdown 语法添加的记事本一级标题

【图 5 使用 Markdown 语法添加的记事本一级标题】

2.1 加载数据

完成上面的准备工作后,就可以加载数据了。原始的 CSV 数据集需要先上传到 Observable 网页,即右侧那个回形针图标:

图 6 将 CSV 原始数据集上传到 Observable 页面

【图 6 将 CSV 原始数据集上传到 Observable 页面】

上传完毕后,可以看到这个文件的相关信息,显示还未被使用:

图 7 文件上传完毕时的页面提示信息

【图 7 文件上传完毕时的页面提示信息】

这个数据集该怎么加载,变成我们需要的对象数组呢?熟悉 Python Jupyter Lab 的朋友肯定很熟悉这样的界面,其实 Observable 就是一个 JavaScript 版的 Jupyter Lab,所有数据操作都在单元格内进行。Observable 提供了 FileAttachment 接口来加载数据,要在 JavaScript 单元格内这样写:

FileAttachment('data.csv')

但这样得到的数据值全是字符串类型的,因此还需要调用一个 csv() 方法,并传入一个配置项,实现简单格式的自动转换:

FileAttachment('data.csv').csv({typed: true});

然后将结果赋给一个常量 data。注意,这里无需添加 constlet 关键字,声明的变量类似 Excel 里的单元格的值,可以全局引用。此外,Observable 的单元格严格遵循“单一职责”原则,因此最好写成 IIFE 形式:

data = (async function(){const data = await FileAttachment('data.csv').csv({typed: true});return data.sort((a, b) => d3.descending(a.count, b.count));
})();

这样,数据加载 + 转换 + 排序就一气呵成轻松实现了!我这里的排序还用到了一个新的工具函数:d3.descending(a.count, b.count)。仔细看,其实我并没有手动导入 D3 这个库,之所以能直接使用,是因为 Observable 已经内置了最新版的 D3.js(别人好歹是创始人,这点特权还是有的)。最后执行单元格的效果如下:

图 8 完成数据加载、转换、排序后的 Observable 页面效果截图

【图 8 完成数据加载、转换、排序后的 Observable 页面效果截图】

2.2 数据绑定

刚才一个单元格就实现了 D3 工作流的三个节点(即查找(文件上传)、加载、格式化),个人感觉比手动去调 Promise 省事多了。下一步就该定义 SVG 容器并绑定数据了。Observable 单元格支持三大基本类型:JavaScript 型、HTML 型以及 Markdown 型。按照书中的方法创建一个 div 元素倒也不是不行,只要在 HTML 格式的单元格里创建 div,再把样式写到一个 style 标签里就搞定了。但是 Observable 提供了更快的方式:

chart = {const svg = d3.create('svg').attr('viewBox', `0 0 600 700`).style('border', '1px solid black').style('max-width', 800).style('margin-inline', 'auto');return svg.node();
}

这段代码的最后一句,相当于导出 DOM 节点并赋值给变量 chart。同样按下 Shift + Enter,页面立刻渲染出了指定的容器:

图 10 执行 d3.create() 方法可以快速创建 SVG 容器

【图 10 执行 d3.create() 方法可以快速创建 SVG 容器】

因此,数据绑定逻辑只要稍加改动就行了:

图 11 改造后的 createViz 方法及其调用的写法

【图 11 改造后的 createViz 方法及其调用的写法】

剩下的工作就简单多了(其实整体来讲也没啥难度)。

2.3 调整比例

于是来到 D3 数据标准工作流的最后一环:调整比例大小。先定义好两个比例尺:

const xScale = d3.scaleLinear().domain([0, data[0].count]).range([0, 450]);const yScale = d3.scaleBand().domain(data.map(d => d.technology)).range([0, 700]).paddingInner(0.2);

由于 data 已经按 count 票数值降序排列,这里水平方向的定义域上边界就是 data[0].count 。接着再使用 D3 的数据绑定语法完成条形图的渲染:

const byTechName = ({technology: t}) =>(t === 'D3.js') ? 'yellowgreen' : 'skyblue';
svg.selectAll('rect').data(data).join('rect').attr('x', 100).attr('y', d => yScale(d.technology)).attr('height', yScale.bandwidth()).attr('width', d => xScale(d.count)).attr('fill', byTechName);

这里填充色的设置做了点小改动,提出了一个访问器函数(accessor function)byTechName,这样写起来更紧凑。最终完整的 createViz 逻辑如下:

createViz = (data, svg) => {// Declare D3's scale functionsconst xScale = d3.scaleLinear().domain([0, data[0].count]).range([0, 450]);const yScale = d3.scaleBand().domain(data.map(d => d.technology)).range([0, 700]).paddingInner(0.2);  // the gap size between 2 bars// data binding logics ...const byTechName = ({technology: t}) =>(t === 'D3.js') ? 'yellowgreen' : 'skyblue';svg.selectAll('rect').data(data).join('rect').attr('x', 100).attr('y', d => yScale(d.technology)).attr('height', yScale.bandwidth())  // i.e. bar height.attr('width', d => xScale(d.count)).attr('fill', byTechName);return svg.node();
};

运行该单元格,上面定义的 chart 单元格就渲染出了想要的条形图:

图 12 最终在 Observable 的记事本页面渲染出的条形图效果

【图 12 最终在 Observable 的记事本页面渲染出的条形图效果】

3 小结 & 复盘

以上演示内容还只是 Observable 平台功能的冰山一角,根据最新发布的新闻,Observable 不久前已经上线了自己的云平台 Observable Cloud,可以像 GitHubnpm 那样在线托管自己的可视化项目,并且提供了大量实用的工具,比如接入了 AI 的能力,专为数据应用量身打造的线上工作流等等。浏览过程中,我发现 D3 官网还没有和 Vue.js 做集成的相关内容,而且 Notebook 页面好像对 Mocha.js 这类测试框架不是很友好,目前只测通了断言库 Chai.js。窃以为,这些地方恰恰蕴藏着大量的机遇,值得各位 D3 爱好者们前来探索!

最后还是梳理成要点,谈谈这趟试水 Observable 平台的切身体会吧:

  1. 大胆尝试 Observable 环境,遇到问题再小心求证;
  2. 多使用 Observable 提供的便捷接口、工具函数。D3.js 的官方入门文档(https://d3js.org/getting-started)是个不错的切入口;
  3. 积极拥抱 D3 生态,不要拘泥于一本书、或者某个单一的环境;
  4. Observable 创建的记事本还能共享给多人访问,实现同步编辑、实时预览;
  5. 多从线上的优秀案例学习 D3.js 的不同写法,取长补短,融会贯通。

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/438830.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode135:分发糖果

步骤1:计算问题性质的定义 我们需要解决的题目是一个典型的贪心算法问题,要求分发糖果的数量,满足特定条件。以下是问题的详细定义: 输入: ratings:长度为 n 的数组,表示每个孩子的评分&#x…

【51单片机】点亮LED之经典流水灯

开发环境 开发板:普中51-单核-A2单片机:STC89C52RC(双列直插40引脚 DIP40)Keil uVision5 v9.61 最新版破解方法自行百度,相关文档和视频资料很多,我自己将这一操作记录下来当做博客发布,CSDN以…

Pikachu-Unsafe FileUpload-客户端check

上传图片,点击查看页面的源码, 可以看到页面的文件名校验是放在前端的;而且也没有发起网络请求; 所以,可以通过直接修改前端代码,删除 checkFileExt(this.value) 这部分; 又或者先把文件名改成…

职业技术学校开设无人机培训技术详解

职业技术学校开设无人机培训技术,是一个涉及多个方面的综合性教学过程。以下是对该培训技术的详细解析: 一、培训目标 无人机培训技术的目标在于培养学员掌握无人机的基本原理、组装调试、飞行操作、安全规范及维修保养等技能,使其成为具备…

【Android】中级控件

其他布局 相对布局RelativeLayout RelativeLayout下级视图的位置是相对位置,得有具体的参照物才能确定最终位置。如果不设定下级视图的参照物,那么下级视图默认显示在RelativeLayout内部的左上角。用于确定视图位置的参照物分两种,一种是与…

Linux环境基础开发工具使用(2)

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 Linux环境基础开发工具使用(2) 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. Li…

Qt Quick 3D 入门:QML 3D场景详解

随着 Qt 6 的发布,QtQuick3D 模块带来了新的 3D 渲染和交互能力,使得在 Qt 中创建 3D 场景变得更加简单和直观。本文将带您从一个简单的 QML 3D 应用开始,详细讲解各个相关领域的概念、代码实现以及功能特点。 什么是 Qt Quick 3D&#xff1…

git维护【.gitignore文件】

在工程下添加 .gitignore 文件【git忽略文件】 *.class .idea *.iml *.jar /*/target/

订阅ROS2中相机的相关话题并保存RGB、深度和点云图

系统:Ubuntu22.04 ROS2版本:ROS2 humble 1.订阅ROS2中相机的相关话题并保存RGB图、深度图和点云图 ros2 topic list/stellar_1/rgb/image_raw /camera/depth/image_raw /stellar_1/points2CMakeLists.txt cmake_minimum_required(VERSION 3.15) projec…

Docker安装人大金仓(kingbase)关系型数据库教程

人大金仓数据库(KingbaseES)是由中国人民大学金仓公司研发的一款自主知识产权的关系型数据库管理系统。 官网地址:https://www.kingbase.com.cn/ 本章教程,主要介绍如何用Docker安装启动人大金仓(kingbase)关系型数据库。 一、下载镜像 下载地址:https://www.kingbase.c…

螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习04(环境准备)

4 创建docker容器 4.1创建网络 [rootlocalhost wutool]# docker network create -d macvlan --subnet192.168.137.0/24 --gateway192.168.137.2 --ip-range192.168.137.0/24 -o parentens33 nat 52af11381bfd655d175e4168265b2a507793e8fe48f119db846949ffd4dd27de [rootlocal…

​IAR全面支持国科环宇AS32X系列RISC-V车规MCU

全球领先的嵌入式系统开发软件解决方案供应商IAR与北京国科环宇科技股份有限公司(以下简称”国科环宇”)联合宣布,最新版本IAR Embedded Workbench for RISC-V将全面支持国科环宇AS32X系列RISC-V MCU,双方将共同助力中国汽车行业开…

文件上传之%00截断(00截断)以及pikachu靶场

pikachu的文件上传和upload-lab的文件上传 目录 mime type类型 getimagesize 第12关%00截断, 第13关0x00截断 差不多了,今天先学文件上传白名单,在网上看了资料,差不多看懂了,但是还有几个地方需要实验一下&#…

自然语言处理问答系统技术

自然语言处理问答系统技术 随着人工智能的不断发展,自然语言处理(NLP)技术已成为推动智能问答系统发展的核心技术。问答系统是利用NLP来解析用户提出的问题,并从知识库中找到最相关的答案。在许多应用中,如智能客服、…

使用python基于DeepLabv3实现对图片进行语义分割

DeepLabv3 介绍 DeepLabv3 是一种先进的语义分割模型,由 Google Research 团队提出。它在 DeepLab 系列模型的基础上进行了改进,旨在提高图像中像素级分类的准确性。以下是 DeepLabv3 的详细介绍: 概述DeepLabv3 是 DeepLab 系列中的第三代…

开启AI新篇章:探索GPT-4与大模型!订阅方案!简单支付!

开启AI新篇章:探索GPT-4的无限可能 随着人工智能技术的飞速发展,我们正处于一个前所未有的变革时代。作为人工智能领域的领导者,OpenAI 推出的GPT-4,以其卓越的自然语言处理能力和强大的计算潜力,引发了行业内外的广泛…

【Android 14源码分析】WMS-窗口显示-流程概览与应用端流程分析

忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…

创建Vue项目的时出现:无法加载文件 E:\software\node\node_global\vue.ps1,因为在此系统上禁止运行脚本

创建Vue项目的时出现的问题:出现:无法加载文件 E:\software\node\node_global\vue.ps1,因为在此系统上禁止运行脚本 解决方法: .PowerShelll的执行政策阻止了该操作,用 get-ExecutionPolicy 查看执行策略的状态为受限 输入Set-ExecutionPo…

【STM32开发之寄存器版】(二)-USART

一、前言 串口作为STM32的重要外设,对程序调试具有不可替代的作用。通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。其主要具备以下特性&am…

CSP-J模拟赛四补题报告

前言 T1: 100 p t s \color{green}100pts 100pts T2: 100 p t s \color{green}100pts 100pts T3: 20 p t s → 5 p t s \color{red}20pts\rightarrow5pts 20pts→5pts T4: 20 p t s \color{red}20pts 20pts T1,2秒了,T3,4死了 T1 三个(three) 题面…