数据可视化【四】Bar Chart

Make a Bar Chart

  • Representing a data table in JavaScript
  • Creating rectangles for each row
  • Using linear and band scales
  • The margin convention
  • Adding axes

以下学习内容参考博客:传送门

select()选择所有指定元素的第一个
selectAll()选择指定元素的全部
上面两个函数返回的结果为选择集
关于 select 和 selectAll 的参数,其实是符合 CSS 选择器的条件的,即用“井号(#)”表示 id,用“点(.)”表示 class。
datum()绑定一个数据到选择集上
data()绑定一个数组到选择集上,数组的各项值分别与选择集的各项元素绑定

在选择集A和给定数据集B进行绑定的时候,会返回一个值,这个值有三种状态。默认然会的是update状态。通过update状态我们还能得到exit状态和enter状态。

  • update:A∩BA\cap BAB
  • exit:A−BA-BAB
  • enter:B−AB-ABA

比较常用的是enter,当我们绑定新数据以后一般要对新数据进行处理。对enter()函数的处理会应用到每个数据上。例如:

svg.selectAll("rect")//选择svg内的所有矩形.data(dataset)//绑定数组.enter()//指定选择集的enter部分.append("rect")//添加足够数量的矩形元素.attr("x",20).attr("y",function(d,i){return i * rectHeight;}).attr("width",function(d){return d;}).attr("height",rectHeight-2).attr("fill","steelblue");

以上面的代码为例。我们对所有的矩形绑定了data以后获得entry,然后对每个数据进行处理。需要注意的是对属性的设置要么是常数要么应该传入一个函数,并且函数可以有两个参数,第一个是数据,第二个是数据的下标。

学习实现代码:https://vizhub.com/Edward-Elric233/b9b751bfae674d0aa65deae87899b710

index.html

<!DOCTYPE html>
<html><head><title>Makign a Bar Chart</title><link rel="stylesheet" href="styles.css"><script src="https://unpkg.com/d3@5.7.0/dist/d3.min.js"></script><!-- find D3 file on UNPKG d3.min.js-->
</head><body><svg width="960" height="500"></svg><script src="./index.js">// console.log(d3); test whether you have imported d3.js or not</script></body></html>

index.js

const svg = d3.select('svg');
// svg.style('background-color', 'red'); test
const width = +svg.attr('width');
const height = +svg.attr('height');const render = data => {const xValue = d => d.population;const yValue = d => d.country;const margin = { top: 20, right: 20, bottom: 20, left: 100 };const innerWidth = width - margin.left - margin.right;const innerHeight = height - margin.top - margin.bottom;const xScale = d3.scaleLinear().domain([0, d3.max(data, xValue)]).range([0, innerWidth]);const yScale = d3.scaleBand().domain(data.map(yValue)).range([0, innerHeight]).padding(0.1);const yAxis = d3.axisLeft(yScale);const xAxis = d3.axisBottom(xScale);const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);//yAxis(g.append('g'));g.append('g').call(yAxis);g.append('g').call(xAxis).attr('transform', `translate(0,${innerHeight})`);let colorSet = ['#eb2617', '#ffaa00', '#4dff00', '#00fbff', '#bb00ff', '#eeff00'];const createGetColor = (idx) => {var i = idx || -1;return {get: () => { i = (i + 1) % colorSet.length; return colorSet[i]; }};};const getColor = createGetColor();g.selectAll('rect').data(data).enter().append('rect').attr('y', d => yScale(yValue(d))).attr('width', d => xScale(xValue(d))).attr('height', yScale.bandwidth()).attr('fill', getColor.get);
};d3.csv("https://gist.githubusercontent.com/Edward-Elric233/23f3024c472ffd7e34e6a5ac04bad26c/raw/6ced2249ea6f5d12f72c1eb00b8c1278d2c86e95/every%2520countries'%2520population").then(data => {data.forEach(d => {d.population = +d.population * 1000;});render(data);// console.log(data);
});

实现效果:在这里插入图片描述

需要注意的是使用d3绑定csv文件的时候要求csv文件不能是本地,必须上传到服务器然后使用http协议访问。我这里使用的是gist.github上传的数据。

这里其他地方都比较简单,主要详细讲解一下js文件。

d3.csv('data.csv').then(data => {data.forEach(d => {d.population = +d.population * 1000;});render(data);

上面的代码主要是读取数据然后再对数据进行处理,处理使用的是我们自己编写的函数render

然后就是render函数。

const xScale = d3.scaleLinear().domain([0, d3.max(data, xValue)]).range([0, innerWidth]);const yScale = d3.scaleBand().domain(data.map(yValue)).range([0, innerHeight]).padding(0.1);

scaleLinear函数用来标注柱状图的刻度。定义域domain是一个范围,值域range也是一个范围,d3会自动进行一个比例映射。这个函数返回一个函数,我们使用xScale(input)输入一个数字d3就会返回一个值,这个值是按照比例进行映射的。

scaleBand函数的定义域是一个数组,值域是一个范围。然后我们可以获取yScale.bandwidth()来确定每个柱状图的宽度(因为是水平的所以其实是高度)。每个条形的y坐标我们可以通过这个函数输入参数获取。例如这里的yScale('China')就会返回一个值,这个值是计算好的,我们不用处理。

其他的就是最前面的做法,使用selectAll获取到所有矩形(此时为空),然后和data进行绑定,然后再对enter进行处理。每个数据都会得到一个矩形并且有相应的坐标。

这里使用xValueyValue函数的原因是因为多个地方都要取数据的属性,我们将这种操作抽象出来以后就只用修改一个地方。

这个代码中和老师讲解不同的是我的柱状图的颜色是五颜六色的。我觉得老师讲都弄成一种颜色太过单调了,就想办法改了一下。主要就是设置了每个矩形的fill属性,传入一个每次会返回不同颜色的函数,如下:

let colorSet = ['#eb2617', '#ffaa00', '#4dff00', '#00fbff', '#bb00ff', '#eeff00'];const createGetColor = (idx) => {var i = idx || -1;return {get: () => { i = (i + 1) % colorSet.length; return colorSet[i]; }};};
const getColor = createGetColor();

这里使用的是通过闭包的方式在函数里面保存了一个累加器,从而实现不断返回新颜色。

Customizing Axes

Formatting numbers

为了使得坐标上的数字变得规格化,我们可以使用d3中的format函数。我们可以在http://bl.ocks.org/zanarmstrong/05c1e95bf7aa16c4768e查看如何进行格式化。

const xAxisTickFormat = number => format('.3s')(number).replace('G','B');
const yAxis = axisLeft(yScale);
const xAxis = axisBottom(xScale).tickFormat(xAxisTickFormat);

Removing unnecessary lines

如果一些东西是多出来的想要进行删除可以在开发者工具中的选择多余的部分查看属性然后用selectremove进行删除。

g.append('g').call(yAxis).selectAll('.domain, .tick line').remove();

Adding a visualization title

g.append('text').attr('y', -10).text('Top 10 Most Population Countries').style('font-size', 40);

Adding axis lables

const yAxisG = g.append('g').call(yAxis).selectAll('.domain, .tick line').remove();const xAxisG = g.append('g').call(xAxis)	.attr('transform', `translate(0,${innerHeight})`);xAxisG.append('text').attr('y', 50).attr('x', innerWidth-60).attr('fill', 'black').text('populiation').style('font-size', 20);

Making tick grid lines

可以将下面的刻度的线弄的很长,比如:

  const xAxis = axisBottom(xScale).tickFormat(xAxisTickFormat).tickSize(-innerHeight);

可是我觉得这样很丑,所以就算了。

课程还介绍了一个关于Data Visualization的一个文档,感兴趣的可以下载:https://github.com/amycesal/dataviz-style-guide/blob/master/Sunlight-StyleGuide-DataViz.pdf

经过上面代码的修改以及颜色的修改,最后的效果图:
在这里插入图片描述

看起来已经比较标准了。vizhub代码:https://vizhub.com/Edward-Elric233/dc1509720f104350a589b46eda59157a

本地代码:

index.html

<!DOCTYPE html>
<html><head><title>Makign a Bar Chart</title><link rel="stylesheet" href="styles.css"><script src="https://unpkg.com/d3@5.7.0/dist/d3.min.js"></script><!-- find D3 file on UNPKG d3.min.js-->
</head><body><svg width="960" height="500"></svg><script src="./index.js">// console.log(d3); test whether you have imported d3.js or not</script></body></html>

index.js

const svg = d3.select('svg');
// svg.style('background-color', 'red'); test
const width = +svg.attr('width');
const height = +svg.attr('height');const render = data => {const xValue = d => d.population;const yValue = d => d.country;const margin = { top: 60, right: 20, bottom: 80, left: 150 };const innerWidth = width - margin.left - margin.right;const innerHeight = height - margin.top - margin.bottom;const xScale = d3.scaleLinear().domain([0, d3.max(data, xValue)]).range([0, innerWidth]);const yScale = d3.scaleBand().domain(data.map(yValue)).range([0, innerHeight]).padding(0.1);const xAxisTickFormat = number => d3.format('.3s')(number).replace('G', 'B');const yAxis = d3.axisLeft(yScale);const xAxis = d3.axisBottom(xScale).tickFormat(xAxisTickFormat);const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);//yAxis(g.append('g'));const yAxisG = g.append('g').call(yAxis).selectAll('.domain, .tick line').remove();const xAxisG = g.append('g').call(xAxis).attr('transform', `translate(0,${innerHeight})`);xAxisG.append('text').attr('class', 'axis-label').attr('y', 60).attr('x', innerWidth / 2).attr('fill', 'black').text('populiation');let colorSet = ['#eb2617', '#ffaa00', '#4dff00', '#00fbff', '#bb00ff', '#eeff00'];const createGetColor = (idx) => {var i = idx || -1;return {get: () => { i = (i + 1) % colorSet.length; return colorSet[i]; }};};const getColor = createGetColor();g.selectAll('rect').data(data).enter().append('rect').attr('y', d => yScale(yValue(d))).attr('width', d => xScale(xValue(d))).attr('height', yScale.bandwidth()).attr('fill', getColor.get);g.append('text').attr('class', 'title').attr('y', -20).text('Top 10 Most Population Countries');
};d3.csv("https://gist.githubusercontent.com/Edward-Elric233/23f3024c472ffd7e34e6a5ac04bad26c/raw/6ced2249ea6f5d12f72c1eb00b8c1278d2c86e95/every%2520countries'%2520population").then(data => {data.forEach(d => {d.population = +d.population * 1000;});render(data);// console.log(data);
});

styles.css

body {margin: 0px;overflow: hidden;font-family: manosapce;
}text {font-family: sans-serif;
}.tick text {font-size: 2em;fill: #8E8883
}.axis-label {fill: #8E8883;font-size: 2.5em
}.title {font-size: 3em;fill: #8E8883
}

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

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

相关文章

数据库原理及应用【三】DBMS+SQL

DBMS Query LanguagesInterface and maintaining tools(GUI)APIsClass Library QL 不是图灵完备的&#xff0c;不是一种编程语言。 QL SQL是一种非过程化的查询语言。 DDL数据定义语言&#xff1a;表&#xff0c;视图QL 查询语言DML 数据操纵语言DCL 数据控制语言 Base t…

数据可视化【五】 Scatter Plot

Scatter Plot vizhub上实现的代码&#xff1a; https://vizhub.com/Edward-Elric233/53807a1b35d94329b3689081cd2ea945 https://vizhub.com/Edward-Elric233/b9647d50899a4a0e8e917f913cd0a53a https://vizhub.com/Edward-Elric233/8c6b50cd81a04f048f490f48e4fe6264 由前…

数据可视化【六】Line Chart Area Chart

Line Chart vizhub代码&#xff1a; https://vizhub.com/Edward-Elric233/094396fc7a164c828a4a8c2e13045308 实现效果&#xff1a; 这里先使用d3.line()设置每个点的x坐标和y坐标&#xff0c;然后再用这个东西设置path的d属性&#xff0c;就可以得到曲线。 const lineGen…

数据可视化【七】 更新模式

Enter 以下面这个简单的代码进行分析 const svg d3.select(svg); // svg.style(background-color, red); testconst height svg.attr(height); // equals paresFloat() const width svg.attr(width);const makeFruit type >( {type} ); //这种写法好像能够直接得到一个…

数据可视化【八】根据数据类型选择可视化方式

Marks:Rows PointsLinesAreas Channels:Columns PositionColorShape

数据可视化【九】单向数据流交互

我们使用一下上上篇博客的代码。 例如我们想要当鼠标点击水果的时候会出现黑色的框&#xff0c;再点击一下黑色的框就会消失。 首先&#xff0c;我们应该给组件添加点击事件&#xff1a; fruitBowl.js gruopAll.on(click, d > onClick(d.id));这个on函数第一个参数是事件…

数据库原理及应用【四】数据库管理系统

查询优化 数据库管理系统中非常重要的一部分。 代数优化 按照一定的规则将语句变化成关系代数以后进行优化 操作优化 对代数优化后的查询树使用比较好的方法进行查询。 主要是对连接运算进行优化 嵌套循环归并扫描索引优化哈希连接 恢复机制 备份&#xff08;完整备份差…

递归式复杂度求解

代换法 猜测复杂度验证是否满足递归式&#xff08;使用归纳法&#xff09;找到常数应该满足的条件针对基本情况&#xff0c;常数足够大时总是成立的 需要注意的是&#xff0c;我们猜测的复杂度有可能不满足递归式&#xff0c;这个时候就要通过减去一些低阶项来使得归纳成立。…

P、NP、NP完全问题、NP难问题

可以在多项式时间内求解的问题称为易解的&#xff0c;而不能在多项式时间内求解的问题称为难解的。 P类问题&#xff1a;多项式类型&#xff0c;是一类能够用&#xff08;确定性的&#xff09;算法在多项式的时间内求解的判定问题。 只有判定问题才属于P 不可判定问题&#…

数据可视化【十】绘制地图

Loading and parsing TOPOJSON 导入Topojson d3文件 地址&#xff1a;https://unpkg.com/topojson3.0.2/dist/topojson.min.js 想要找d3文件的话去unpkg.com好像大部分都能找到的样子 Rendering geographic features 寻找合适的地图数据&#xff1a;谷歌搜索world-atlas npm…

数据可视化【十一】树状图

Constructing a node-link tree visualization 首先将节点之间的连线画出来。 使用json函数读取文件以后&#xff0c;使用hierarchy等函数得到连线的数组&#xff0c;然后绑定这个数组&#xff0c;给每个元素添加一个path&#xff0c;绘画使用的是一个函数linkHorizontal&…

数据可视化【十二】 颜色图例和尺寸图例

有了前面的知识&#xff0c;制作一个图例应该不是很难&#xff0c;关键是我们想要制作一个可以在其他地方进行使用的图例&#xff0c;这样就需要能够动态地设置图例的大小&#xff0c;位置&#xff0c;等等。 这里直接上代码&#xff1a; colorLegend.js export const color…

数据可视化【十三】地区分布图

在前面的博客中已经介绍了如何绘制地图&#xff0c;这一节学习如何绘制地区分布图。如果对绘制地图还不熟悉的话可以了解一下之前我写的博客&#xff1a;数据可视化【十】绘制地图 Intergrating(整合) TopoJSON with tabular data(列表数据) 在前面的博客中没有使用到tsv文件…

数据可视化【十四】交互式过滤地区分布图

在前面的博客中已经介绍了如何绘制地区分布图&#xff0c;这一节学习如何绘制交互式过滤地区分布图。如果对绘制地区分布图还不熟悉的话可以了解一下之前我写的博客&#xff1a;数据可视化【十三】地区分布图 整体的框架仍然是在之前的基础上进行修改&#xff0c;主要是添加交…

Ubuntu环境搭建

本文记录了一些常用的Ubuntu软件 然后首先修改软件源&#xff1a;软件和更新->Ubuntu软件->下载自&#xff1a;其他站点&#xff08;修改为阿里云&#xff09; 在关闭的时候需要更新什么的 然后修改更新方式&#xff0c;将不支持的更新去掉 常用的Windows软件 网易云…

Ubuntu修改/删除主目录下的中文文件夹

在Ubuntu的主目录下一般是有一些中文的目录&#xff0c;例如桌面&#xff0c;视频等等&#xff0c;还无法修改名称&#xff0c;在一群英文文件夹里面显得有些突兀&#xff08;Ubuntu终端下的中文一点也不好看&#xff09;&#xff0c;就想把这些文件夹修改一下&#xff0c;结果…

每日一题:leetcode1489. 找到最小生成树里的关键边和伪关键边

时隔多年我终于又开始写博客了&#xff0c;主要是已经放假了&#xff0c;之前一直忙于考试和课设没有时间写博客&#xff0c;学习笔记也因为买了iPad的缘故大部分都是手写的了。 假期想要把以前做过的项目都整理一下放在github和CSDN上。 也已经很久没有写算法题了&#xff0…

每日一题:leetcode989.数组形式的整数加法

题目描述 题目分析 题目非常简单&#xff0c;但是我还是wa了几发&#xff0c;对不起&#xff0c;我太菜了。我的想法是把K转换为数组然后用大整数加法处理。但是因为太久没有写了导致写了好久。 class Solution { public:void add(vector<int> &A, vector<int&g…

每日一题:leetcode674.最长连续递增序列

题目描述 题目分析 一遍遍历&#xff0c;如果硬要说用了什么算法的话觉得应该算是一个简单的滑动窗口吧 AC代码 class Solution { public:int findLengthOfLCIS(vector<int>& nums) {if (nums.size() 0) {return 0;}int ret 1;int cnt 1;for (int i 1; i <…

每日一题:leetcode959.由斜杠划分区域

题目描述 题目分析 仔细分析这道题以后虽然觉得可能要转化为图之类的&#xff0c;但是完全没有具体的想法&#xff0c;因为每个格子都有三种情况&#xff0c;这三种情况的不同的组合又会产生不同的结果。 发现找不到编码转化为图以后&#xff0c;我分析了一下不同数量方块之间…