d3成神之路(一):先从柱状图开始

2022-01-24 15:00:00 浏览数 (1)

上周五我再团队里完成了前端qiankun微服务架构单镜像部署方案的分享,这件事终于告一段落了,这件事本身是一件很有价值的事情,能够较低很大的部署,运维成本。但由于研究期间本职的工作内容排的很满,而且中间又经历了曲折的绩效考核。所以一拖再拖。终于告一断落了。

于是我开始思考,下一阶段研究点什么那? 除了工作之外的学习内容,我给自己的要求是必须要学点区别于其他人的,着眼于未来的学习内容。在接触了node-red 与 butterfly 之后,我发现它们都使用了d3,大家一致都说d3是一个学习曲线很陡的js库,网上一直有他的传说。 很多优秀的软件只是用了太它的一点皮毛,就让软件增色很多,比如node-red的节点编排,butterfly的节点排版。所以我决定花点时间,好好学习一下它。

首先我先大致浏览了d3的文档,然后看了b站的使用d3进行数据可视化编程的视频。 感觉也不是很难吧,相对于echarts具有丰富的案例,d3只是提供很底层的api,想创造什么,看你的创造力了。

如果不知道的怎么学习一样东西时,可以先试着模仿。 用d3做一些常用的图表,照着echarts的案例做。 人类最开始的学习就是模仿。 就像我的女儿学习拍手,走路,吃饭。

学习d3先来个柱状图吧 照着b站的视频,我也敲出来了这样一个柱状图。

很简单的一个柱状图,但用到的知识却很多,坐标系,比例尺,svg操作,一个基础图例用到的都用到了。

下面我来总结一下开发的思路。 首先定义svg,与源数据 svg 的容器

代码语言:javascript复制
<svg width="1600" height="800" id="main" class="svg"></svg>

使用的源数据

代码语言:javascript复制
const data = [
   {name: 'a', value: 1},
   {name: 'b', value: 2},
   {name: 'c', value: 3},
   {name: 'd', value: 4},
   {name: 'e', value: 5},
]

获取容器和设置容器的margin

代码语言:javascript复制
const svg = d3.select('#main');
const width = svg.attr('width');
const height = svg.attr('height');
const margin = {top: 60, right:30, bottom: 60,left:50}
const innerWidth = width - margin.right - margin.left
const innerHeight = height - margin.top - margin.bottom

然后就是创建x轴的比例尺,和y轴的比例尺

代码语言:javascript复制
const xScale = d3.scaleLinear()
                 .domain([0, d3.max(data, d => d.value)])
                 .range([0, innerWidth])

const yScale = d3.scaleBand()
                 .domain(data.map(x => x.name))
                 .range([0, innerHeight])
                 .padding(0.5)

注意新的api的使用d3.scaleLinear()d3.scaleBand()domain()range() , padding()。我们一个一个学习一下。

d3.scaleLinear() 创建一个连续线性的比例尺,就是连续数字的映射。。简单地说,比例尺就相当于是一个函数,让我们把一组定义域映射到值域。 后面的domain()和range(),两个函数都是又来修饰 该比例尺的。常见的使用场景时这样的, svg 长 1200px,我们可以将 0到1200 映射成 0到原数据的最大值。这样,原数据中的任意一个值都可以使用该比例尺找到自己的位置。所以 domain()函数是用来设置定义域,range()是用来设置值域的。

domain的参数取自 数据集中, range的参数取自容器 svg的长宽。

scaleBand() 创建一个序列的条状比例比例尺,它的定义域是一个类目的集合,如,['苹果','橘子','梨','香蕉','火龙果','西瓜'] 在这里 定义域就是 domain(data.map(x => x.name)) 元数据名称的集合。

设置完比例尺 就要设置 坐标轴 和渲染数据了

代码语言:javascript复制
const g = svg.append('g').attr('id', 'maingroup').attr('transform',`translate(${margin.left},${margin.top})`)
const yAxis = d3.axisLeft(yScale)
g.append('g').call(yAxis)

const xAxis = d3.axisBottom(xScale)
g.append('g').call(xAxis).attr('transform', `translate(0, ${innerHeight})`)

data.forEach(d => {
    g.append('rect')
    .attr('width', xScale(d.value))
    .attr('height', yScale.bandwidth())
    .attr('fill', 'green')
    .attr('y', yScale(d.name))
})

代码解释,待续。。。

0 人点赞