d3成神之路(五):扇形图,饼图

2022-01-24 15:01:45 浏览数 (2)

制作扇形其实也是使用 svg的 path 这个属性, 重要的是计算各个扇形区域的点,与弧度 效果图

首先需要使用源数据 生成相应的弧度信息

使用d3.pie()

代码语言:javascript复制
const data = [1, 1, 2, 3, 5, 8, 13, 21];
const arcs = d3.pie()(data);

生成弧度后 再使用 d3.arc() 来进行绘制 path

代码语言:javascript复制
const arc = d3.arc()
      .innerRadius(0)
      .outerRadius(Math.min(innerWidth, innerHeight) / 2 - 1)

这里还学到一个技巧 就是 使用源数据的某一个属性来生成一个颜色

代码语言:javascript复制
const color = d3.scaleOrdinal()
      .domain(data.map(d => d.name))
      .range(d3.quantize(t => d3.interpolateSpectral(t * 0.8   0.1), data.length).reverse())

详细代码

代码语言:javascript复制
<!DOCTYPE html>
<html>

<head>
  <title>基础饼图</title>
  <link rel="stylesheet" href="../../css/index.css">
</head>

<body>

  <svg id="main" width="800" height="600"></svg>

  </div>

  <script src="../../js/d3.min.js"></script>
  <script src="../../js/mchart.js"></script>
  <script>

    function getSvgInfo() {
      const svg = d3.select("#main")
      const width = svg.attr('width')
      const height = svg.attr('height')
      const margin = { top: 30, right: 60, bottom: 30, left: 60 }
      const innerHeight = height - margin.top - margin.bottom
      const innerWidth = width - margin.left - margin.right
      const config = {
        colors: [
          "#5470c6",
          "#91cc75",
          "#fac858",
          "#ee6666",
          "#73c0de",
          "#3ba272",
          "#fc8452",
          "#9a60b4",
          "#ea7ccc"
        ],
        opacity: 0.8,
        tickTxt: {
          fontSize: '2em',
          color: '#6E7079'
        },
        chartTitle: {
          text: '基础饼图',
          fontSize: '18px',
          color: '#464646'
        }
      }

      return {
        svg,
        width,
        height,
        margin,
        innerHeight,
        innerWidth,
        config
      }
    }

    const data = [
      { value: 1048, name: '搜索引擎' },
      { value: 735, name: '直接访问' },
      { value: 580, name: '邮件营销' },
      { value: 484, name: '联盟广告' },
      { value: 300, name: '视频广告' }
    ]

    const {
      svg,
      width,
      height,
      margin,
      innerHeight,
      innerWidth,
      config
    } = getSvgInfo()

    const chart = svg.append('g')
      .attr('id', 'maingroup')
      .attr('transform', `translate(${margin.left},${margin.top})`)

    const arc = d3.arc()
      .innerRadius(0)
      .outerRadius(Math.min(innerWidth, innerHeight) / 2 - 1)

    const color = d3.scaleOrdinal()
      .domain(data.map(d => d.name))
      .range(d3.quantize(t => d3.interpolateSpectral(t * 0.8   0.1), data.length).reverse())

    const pie = d3.pie()
      .sort(null)
      .value(d => d.value)

    const arcs = pie(data);

    chart.append("g")
      .attr("stroke", "white")
      .selectAll("path")
      .data(arcs)
      .join("path")
      .attr('transform', `translate(300,300)`)
      .attr("fill", d => color(d.data.name))
      .attr("d", arc)

    setChartTitle(chart)


    function setChartTitle(chart) {
      chart.append('text').text(config.chartTitle.text)
        .attr('font-size', config.chartTitle.fontSize)
        .attr('color', config.chartTitle.color)
        .attr('transform', `translate(${innerWidth / 2}, ${-10})`)
        .attr('text-anchor', 'middle')
        .attr('font-weight', 'bold')
    }



  </script>
</body>

</html>

https://github.com/d3/d3-shape/blob/v3.0.1/README.md#pies

这里再补充一下 d3-shape 这个库的一些特性

Arcs 弧度

Pies 饼图 Lines 线性

Areas 面积

Curves 曲线

Custom Curves 自定义曲线 Links 连线

Symbols 多边形

Custom Symbol Types 自定义 多边形 Stacks 堆积,叠加

0 人点赞