【d3.js入门】基本面积图动画实例

477 阅读3分钟

上一篇文章我们讲了【d3.js入门】基本面积图动画,这篇文章我们基于简单的面积图来开发一个有趣的小案例。

实现思路:

  • 绘制面积图图
  • 绘制很多面积图
  • 让面积图高低有层级感
  • 让面积图填充渐变色
  • 层级不同颜色有变化
  • 让面积图躁动起来

哦,这个案例在B站有视频讲解,有兴趣的jy可以移步观看:【可视化100天-4】层峦叠嶂山水画 www.bilibili.com/video/BV1wK…

water.gif

下面是主要的绘制函数。接下来我将对其代码进行解释。

private drawArea(data, colors, vmax) {
    data.map((d, i) => {
        d.id = i;
    })

这里定义了一个私有函数drawArea,它接受三个参数:datacolorsvmax。首先,我们使用map方法遍历数据数组,并将每个元素的索引赋值给id属性。

    const gline = this.backg.selectAll('g').filter('.areag')
        .data(data)
        .join("g")
        .attr('class', 'areag')

接下来,我们定义一个选择集gline,并使用filter方法选择具有.areag类的g元素。对于每个数据元素,我们使用join方法创建一个g元素,并将其class属性设置为areag

    let gwmax = this.domdiv.offsetWidth
    let ghmax = this.domdiv.offsetHeight

    data.map(d => {

        const data = d.data;
        let scale = d3.scaleLinear()
            .domain([0, vmax])
            .rangeRound([ghmax, 0])//y轴 
        let scale2 = d3.scaleLinear()
            .domain([0, data.length - 1])
            .rangeRound([0, gwmax]) // x轴
        const arr = [];
        data.map((e, i) => {
            arr.push([scale(e), scale2(i)])
        })

        d.sdata = arr;
    })

然后,我们定义了gwmaxghmax变量,分别表示绘图区域的宽度和高度。接下来,我们遍历数据数组,并为每个数据元素创建一个比例尺。这里,我们使用scaleLinear方法创建了一个线性比例尺,它的定义域为[0, vmax],值域为[ghmax, 0]。这个比例尺用于将数据映射到y轴。我们还创建了一个线性比例尺,它的定义域为[0, data.length - 1],值域为[0, gwmax]。这个比例尺用于将数据映射到x轴。

接下来,我们创建一个空数组arr,并使用map方法遍历数据数组。对于每个数据元素,我们将其转换为一个二元数组,其中第一个元素是其在y轴上的坐标值,第二个元素是其在x轴上的坐标值。将这些二元数组添加到arr数组中。最后,我们为每个数据元素添加sdata属性,并将其设置为arr数组。

    const area = d3.area()
        .curve(d3.curveMonotoneX)
        .x((d, i) => { return d[1] })
        .y1((d) => { return d[0] })
        .y0(ghmax);

    gline.selectAll('path').filter('.area')
        .data(d => [d])
        .join('path')
        .attr('class', 'area')
        .attr('fill', d => `url(#linearA${d.id}${this.__id})`)
        .attr('d', d => {
            return area(d.sdata)
        })
}

最后,我们定义了一个area对象,它表示一个区域生成器。我们使用curve方法设置了曲线插值方式,并分别使用xy1y0方法设置了该区域的x、y坐标值。然后,我们选择所有.area类的path元素,并使用join方法创建path元素。我们为每个path元素设置class属性为area,并将其fill属性设置为一个线性渐变。最后,我们使用sdata属性中存储的数据来设置d属性,该属性表示该区域的路径。