D3.js v5.0 主题河流

emmm其实写到这里的话也差不多写完了基本的图形实现。因为先接触的v3.0+版的D3,现在是v5.0+的,写法上差别比较大,加上全是英文的API真的是硬伤。但是实现思路还是差不多的。有写错的请指正。有写的不好的地方请忽略。
对于这个主题河流图,应该这么叫?
我最开始的想法
是和堆栈图联系起来的,想法是使用区域转换器d3.area()
但是报错了,脑子糊了没找出来原因,所以放弃了。
所以有大佬写出来的话,希望可以指导一下。

老规矩,先看图。
D3.js v5.0 主题河流_第1张图片

import * as d3 from 'd3';

export default function stackRect(id) {
  (() => {
    d3.select(id)
      .selectAll('svg')
      .remove();
  })();
  const height = 800;
  const width = 800;
  const padding = {
    left: 100,
    right: 100,
    top: 100,
    bottom: 100,
  };

  const axisHeight = height - padding.top - padding.bottom;
  const axisWidth = width - padding.left - padding.right;
  const z = d3.interpolateCool;

  // 画布
  const svg = d3
    .select(id)
    .append('svg')
    .attr('width', width)
    .attr('height', height);
  const n = 10; //  层的总数
  const m = 50; //  每层的样本数目
  const k = 50; // 每层的颠簸总数

  const stack = d3
    .stack()
    .keys(d3.range(n))
    .offset(d3.stackOffsetWiggle);

  const layers0 = stack(
    d3.transpose(
      d3.range(n).map(function() {
        return bumps(m, k);
      })
    )
  );

  const layers1 = stack(
    d3.transpose(
      d3.range(n).map(function() {
        return bumps(m, k);
      })
    )
  );
  // 将layers1和layers0两个矩阵连接起来
  const layers = layers0.concat(layers1);

  // 定义x轴比例尺
  const x = d3
    .scaleLinear()
    .domain([0, m - 1])
    .range([0, axisWidth]);

  // 定义y轴比例尺
  const y = d3
    .scaleLinear()
    // 定义定义域
    .domain([d3.min(layers, stackMin), d3.max(layers, stackMax)])
    // 定义值域
    .range([axisHeight, 0]);

  const area = d3
    .area()
    .x(function(d, i) {
      return x(i);
    })
    .y0(function(d) {
      return y(d[0]);
    })
    .y1(function(d) {
      return y(d[1]);
    });
  svg
    .selectAll('path')
    .data(layers0)
    .enter()
    .append('path')
    .attr('d', area)
    .attr('fill', function() {
      return z(Math.random());
    });

  // 获取堆栈数据矩阵的最大值
  function stackMax(layer) {
    return d3.max(layer, function(d) {
      return d[1];
    });
  }

  // 获取堆栈数据矩阵的最小值
  function stackMin(layer) {
    return d3.min(layer, function(d) {
      return d[0];
    });
  }
}
// 该方法用于生成长度为n的数组,其中通过m次颠簸,即调用dump(a,n)方法来变换a数组,最终返回变换后的a数组
function bumps(n, m) {
  const a = [];
  let i;
  for (i = 0; i < n; i += 1) a[i] = 0;
  for (i = 0; i < m; i += 1) bump(a, n);
  return a;
}

// 该方法通过一定的随机数的运算来变换数组a的值
function bump(a, n) {
  const x = 1 / (0.1 + Math.random());
  const y = 2 * Math.random() - 0.5;
  const z = 10 / (0.1 + Math.random());
  for (let i = 0; i < n; i += 1) {
    const w = (i / n - y) * z;
    // eslint-disable-next-line no-param-reassign
    a[i] += x * Math.exp(-w * w);
  }
}

你可能感兴趣的:(D3.js)