关于javascript:D3js-绘制柱状图二

20次阅读

共计 2505 个字符,预计需要花费 7 分钟才能阅读完成。

前言

上一篇文章 咱们讲了 D3.js 中一些常见的 API,并且通过一个 demo 理解了 D3.js 是如何工作的。铺垫完之后,这篇文章咱们正儿八经的来实现一个柱状图。

注释

比例尺

比例尺是 D3.js 中一个重要的概念,它用于在值和坐标之间的互相转换。本文中呈现的相干 API 如下👇

API 阐明
scaleBand 个别用于将一组离散值映射到间断范畴的值
scaleLinear 线性转换,将间断的输出域映射到间断的输入范畴

设想一下,咱们须要在一个 800 x 600 宽高的容器内绘制一个坐标系。通常状况下,坐标的数值不会与理论的宽高齐全对应。因而,咱们须要一种工具来将理论的宽高与坐标系中的数值进行映射。

对于 scaleLinear 这个线性转换函数,能够用上面的公式来形容:

$y = mx + b(b 为任意常量)$

通过输出 $x$(通常是一个数值),咱们能够取得元素在页面上的高度或宽度。

绘制坐标系

首先咱们先增加初始代码:引入 D3.js & 设置根底款式

<html>
<head>
    <title>Bar</title>
    <style>
        #bar {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
<div id="bar"></div>
</body>
<script src="<https://d3js.org/d3.v7.min.js>"></script>
</html>

紧接着咱们来创立一个 svg,宽高为:800 x 600

const width = 800;
  const height = 600;
  const data = Array.from({length: 26}).map((_, i) => ({name: String.fromCharCode(65 + i),
    value: Math.random() * 100}))

  const svg = d3.select('#bar')
    .append('svg')
    .attr('width', width)
    .attr('height', height)

此时页面上仍旧是赤裸裸的一片,没关系,咱们先把 x 轴加上:

const xScale = d3.scaleBand().domain(data.map(item => item.name)).range([0, 500]).padding(0.1)
const xAxis = d3.axisBottom(xScale)
svg.append('g').call(xAxis)

此时,页面曾经呈现了咱们须要的 x 轴

随后咱们把 y 轴也加到页面上:

const yScale = d3.scaleLinear().domain([0, 100]).range([500, 0])
const yAxis = d3.axisLeft(yScale)
svg.append('g').call(yAxis)

此时页面就会呈现一个奇怪的坐标系😱😱😱

当然如果你看完了上一篇文章,你就晓得这是因为坐标原点在左上角导致的🤔

因而咱们在绘制 x 轴的时候还须要把它的地位调整一下

svg.append('g').attr('transform', `translate(0, 500)`).call(xAxis

那么写到这里,咱们就失去了一个长得挺难看的坐标系

增加柱状图

增加坐标系之后,咱们就能够开始增加柱状图了。

在此之前有一些细节须要阐明:咱们能够利用 xScaleyScale 来依据网页上理论须要展现的值,来决定柱状图的展现地位。比方,上面这段代码:

const xScale = d3.scaleBand().domain(data.map(item => item.name)).range([0, 500]).padding(0.1)

执行之后,咱们能够通过 name → value 的映射,来获取 x 轴上每一个离散点的具体位置,同理 y 轴也是如此。

依据这点,咱们就不须要再花太多工夫计算每个矩形的的 x、y 坐标了,而是能间接通过 xScaleyScale 这些函数来进行简略的换算来达到咱们想要的成果。代码如下:

svg.selectAll('rect')
    .data(data)
    .join('rect')
    .attr('x', item => xScale(item.name))
    .attr('y', item => yScale(item.value))
    .attr('width', xScale.bandwidth())
    .attr('height', item => 500 - yScale(item.value))
    .attr('fill', 'steelblue')

成果如下👇

补充动画

D3.js 中的动画逻辑是这样的:

  1. 设置初始值,比方 x、y
  2. 增加动画配置,比方动画函数、持续时间等等
  3. 设置最终值,比方 widthheight
svg.selectAll('rect')
    .data(data)
    .join('rect')
    // 设置 x 坐标,避免动画时呈现抖动
    .attr('x', item => xScale(item.name))
    .attr('y', 500)
    // 设置宽度,柱状图的宽度在这里始终放弃不变即可
    .attr('width', xScale.bandwidth())
    // 为了有动画成果,这里先设置高度为 0
    .attr('height', 0)
    .transition()
    // 设置提早
    .delay((item, i) => i * 20)
    // 增加动画函数
    .ease(d3.easeCubic)
    // 设置动画时长
    .duration(1000)
    // 最终的成果
    .attr('y', item => yScale(item.value))
    .attr('height', item => 500 - yScale(item.value))
    .attr('fill', 'steelblue')

总结

本文中咱们理解了比例尺并且相熟了 D3.js 中一些与之相干的 API,并且通过一系列步骤理解了怎么通过 D3.js 来实现一个柱状图。

想要理解更多前端常识,欢送关注我的公众号:tony 老师的前端补习班

系列文章:

  • D3.js —— 绘制柱状图(一)
  • D3.js —— 绘制柱状图(二)

正文完
 0