D3篇之绘制基本图形

发布时间:2024年01月10日

数据准备:<div ref="dataRef" :class="$style.dataRef"></div>

 const fData = [
        {
          name: '香蕉',
          value: 20
        },
        {
          name: '苹果',
          value: 30
        },
        {
          name: '李子',
          value: 90
        },
        {
          name: '猕猴桃',
          value: 10
        },
        {
          name: '橙子',
          value: 60
        }
      ];
      const margin = { left: 30, top: 30, bottom: 30, right: 30 };
      const width = 300;
      const height = 300;
      const svg = d3.create('svg').attr('viewBox', [30, 30, width, height]);
      //...要进行的操作
      this.$refs.dataRef.appendChild(svg.node());

1.柱状图?

scaleBand

  • 适用于离散型数据或分类数据,比如类别、名称等,而不是连续的数值。
  • 常用于创建序数型比例尺(Ordinal Scale),它将离散的输入域映射到有限的输出范围内。
  • domain 包含离散的、有限的值,通常是类别的名称或者离散的标识。
  • 通常用于创建柱状图、分组条形图等,以及将分类数据映射到屏幕上的位置。

const x = d3
? .scaleBand()
? .domain(['A', 'B', 'C', 'D']) // 例如,类别或离散标识
? .range([0, width])
? .padding(0.1);?

?1-1.绘制x轴

const x = d3
        .scaleBand()
        .domain(d3.map(fData, d => d.name))
        .range([margin.left, width - margin.left]);
      const xAxis = d3.axisBottom(x).tickSizeOuter(0);
      svg
        .append('g')
        .attr('transform', `translate(${margin.left},${height - margin.bottom})`)
        .call(xAxis);

1-2.绘制y轴

scaleLinear

  • 适用于连续型数据,比如数值型数据。
  • 创建的是线性比例尺(Linear Scale),将输入域的连续范围映射到输出范围内。
  • domain 包含连续的数值范围,通常是最小值到最大值的数值范围。
  • 通常用于创建折线图、散点图等,以及将数值数据映射到屏幕上的位置。
 const y = d3
        .scaleLinear()
        .domain([min, max])
        .range([margin.bottom, height - margin.bottom]);
      const yAxis = d3.axisLeft(y);
      svg.append('g').attr('transform', `translate(${margin.left},0)`).call(yAxis);

?

是不是很惊奇,为什么压轴是从上往下变大的?

? ? ? 在可视化中,特别是在屏幕坐标系中,通常情况下,y轴的原点通常位于屏幕的左上角,而不是传统的数学坐标系中的左下角。在屏幕坐标系中,y轴向下增长,这与我们在数学课堂上使用的笛卡尔坐标系中y轴向上增长是不同的。

这种不同是因为计算机图形学的历史和屏幕显示的方式导致的。在大多数图形库中,包括D3.js,在渲染坐标轴时,默认情况下会将y轴从上到下显示,这也是为了与屏幕坐标系的方向保持一致。

虽然y轴的增长方向与我们直觉上的数学坐标系不同,但在实际的可视化中,这种方向是合理的,并且符合我们对屏幕空间的感知。如果你想要y轴向上增长,可以通过反转坐标轴的range来实现

?

const y = d3.scaleLinear().domain([min, max]).range([height - margin.bottom, margin.bottom]);

1-3.画条形图

在页面中添加rect和text实现条形图

?

修改之前代码如下:

svg
        .append('g')
        .attr('transform', `translate(0,${height - margin.bottom})`)
        .call(xAxis)
        .call(g => {
          g.selectAll('.tick')
            .append('rect')
            .data(fData)
            .join('rect')
            .attr('width', 30)
            .attr('height', d => height - margin.bottom - y(d.value))
            .attr('fill', 'pink')
            .attr('transform', d => `translate(-15,-${height - margin.bottom - y(d.value)})`);
        })
        .call(g =>
          g
            .selectAll('.tick')
            .append('text')
            .data(fData)
            .join('text')
            .attr('class', 'txt')
            .attr('x', 0)
            .attr('y', d => -(height - margin.bottom - y(d.value)) - 5)
            .attr('text-anchor', 'middle')
            .attr('fill', 'red')
            .text(d => d.value)
        );

?

2.折线图

绘制x轴和y轴原理同上,不同的就吧条形图换成折线图,下面仅是实现折现代码

2-1.绘制折现?

在数据可视化中,曲线(Curves)通常指的是用来平滑连接数据点的线条或路径。在 D3.js 中,有多种类型的曲线插值器可以用来创建平滑的曲线路径,用于连接给定的数据点。

d3.line() 是 D3.js 中的一个函数,用于创建生成器(Generator)。这个生成器可以将输入的数据点数组转换为 SVG <path> 元素所需的路径字符串,以便在 SVG 中绘制线条或曲线。

通常,d3.line() 生成器会配置以下属性:

  • x: 用于确定数据点的 x 坐标的函数或值。
  • y: 用于确定数据点的 y 坐标的函数或值。
  • curve: 确定路径的曲线插值器类型,例如线性、基数样条、单调等。

使用 D3.js 创建的 line 可以将数据点转换为 SVG 中的路径,然后将这个路径添加到 SVG 中以显示图形。要将 line 添加到 SVG 中,你需要将路径数据绑定到一个 SVG 元素上,并将路径信息设置为这个元素的 d 属性。

const line = d3
        .line()
        .x(d => x(d.name))
        .y(d => y(d.value))
        .curve(d3.curveLinear);//d3.curveLinear可根据官网更改
      svg
        .append('path')
        .datum(fData)
        .attr('d', line)
        .attr('fill', 'none')
        .attr('stroke', 'steelblue')
        .attr('stroke-width', 2);

?

2-2.给折线图添加面积?

?

 const area = d3
        .area()
        .x(d => x(d.name)) // 定义x坐标
        .y0(height - margin.bottom) // 定义y坐标的底部值,通常是图表底部
        .y1(d => y(d.value)); // 定义y坐标的顶部值,基于数据的值

      svg.append('path').datum(fData).attr('d', area).attr('fill', 'steelblue').attr('opacity', 0.4);

注意:这里x轴要添加.paddingInner(1)设置分组间的内边距

Band scales | D3 by Observable

3.饼图

Arcs | D3 by Observable

Pies | D3 by Observable?

3-1.数据转换弧度

?const pie = d3.pie()(fData.map(d => d.value));

?

arc弧形生成器产生圆形或环状扇形,例如馅饼或甜甜圈图表。弧线以原点为中心;变换来将弧线移动到不同的位置。?

 const pie = d3.pie()(fData.map(d => d.value));
      // 设置每个值的弧度
      const arc = d3
        .arc()
        .innerRadius(0)
        .outerRadius(80)
        .startAngle(d => d.startAngle)
        .endAngle(d => d.endAngle);
      svg
        .selectAll('g')
        .data(pie)
        .join('g')
        .attr('transform', 'translate(100,100)')
        .call(g =>
          g
            .append('path')
            .attr('d', arc)
            .attr('fill', (d, i) => {
              const color = d3.schemeCategory10;
              return color[i];
            })
        )
        .call(g =>
          g
            .append('text')
            .attr('transform', d => `translate(${arc.centroid(d)})`)
            .attr('text-anchor', 'middle')
            .attr('fill', 'white')
            .text(d => d.value)
        );

?

4.雷达图

未完待续

文章来源:https://blog.csdn.net/ae_pppppp/article/details/135503965
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。