学习D3.js(七)基础散点图

615 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

开始绘制

引入D3模块

  • 这里的模块为官网CDN模块,注意不是长久有效的。
  <!-- 选择器模块 -->
  <script src="https://cdn.jsdelivr.net/npm/d3-selection@3"></script>

  <!-- 比例尺模块 和 依赖 -->
  <script src="https://cdn.jsdelivr.net/npm/d3-array@3"></script>
  <script src="https://cdn.jsdelivr.net/npm/d3-color@3"></script>
  <script src="https://cdn.jsdelivr.net/npm/d3-format@3"></script>
  <script src="https://cdn.jsdelivr.net/npm/d3-interpolate@3"></script>
  <script src="https://cdn.jsdelivr.net/npm/d3-time@3"></script>
  <script src="https://cdn.jsdelivr.net/npm/d3-time-format@4"></script>
  <script src="https://cdn.jsdelivr.net/npm/d3-scale@4"></script>

  <!-- 坐标轴 -->
  <script src="https://cdn.jsdelivr.net/npm/d3-axis@3"></script>

  <!-- 动画 -->
  <script src="https://cdn.jsdelivr.net/npm/d3-dispatch@3"></script>
  <script src="https://cdn.jsdelivr.net/npm/d3-ease@3"></script>
  <script src="https://cdn.jsdelivr.net/npm/d3-timer@3"></script>
  <script src="https://cdn.jsdelivr.net/npm/d3-transition@3"></script>

数据

  • 自定义数据格式。
    var dataArr = [
      {
        x: 70.5,
        y: 0.5
      },
      {
        x: 30.5,
        y: 30.5
      },
      {
        x: 50.5,
        y: 20.5
      },
      {
        x: 60.5,
        y: 10.5
      },
      {
        x: 20.5,
        y: 70.5
      },
      {
        x: 70.5,
        y: 70.5
      },
      {
        x: 60.5,
        y: 90.5
      },
      {
        x: 70.5,
        y: 10.5
      },
      {
        x: 10.5,
        y: 30.5
      },
      {
        x: 30.5,
        y: 20.5
      }
    ]

添加画布

  • 初始化画布。
    var width = 460
    var height = 450
    var margin = 20

    var svg = d3
      .select('.d3Chart')
      .append('svg')
      .attr('width', width)
      .attr('height', height)
      .style('background-color', '#1a3055')

    // 图
    var chart = svg.append('g').attr('transform', `translate(${margin * 2}, ${margin})`)

创建比例尺

  • 根据需求创建比例迟。
// 线性比例尺
var xScale = d3.scaleLinear().range([0, 400]).domain([0, 100])

// 线性比例尺 - Y轴在底部 所以 400 坐标 对应Y轴 开始点
var yScale = d3.scaleLinear().range([400, 0]).domain([0, 100])

绘制坐标轴

  • 和折线图一样,根据比例尺使用axis模块自动绘制坐标轴。
    // 坐标轴
    const xAxis = d3.axisBottom(xScale).tickSize(-400)
    chart.append('g').attr('transform', `translate(0, ${400})`).call(xAxis)
    // 坐标轴
    const yAxis = d3
      .axisLeft()
      .scale(yScale)
      .tickSize(-400)
      .tickFormat((d) => {
        return d + '%'
      })
    chart.append('g').attr('transform', 'translate(0, 0)').call(yAxis)
    d3.selectAll('.d3Chart text').style('fill', '#fff')
    d3.selectAll('.d3Chart line').style('stroke', '#fff')
    d3.selectAll('.d3Chart path').style('stroke', '#fff')

image.png

  • .tickSize() 设置x轴、Y轴刻度的长度为400,形成网格。

绘制散点

    chart
      .append('g')
      .selectAll()
      .data(dataArr)
      .enter()
      .append('circle')
      .attr('class', 'point')
      .attr('cx', (d) => xScale(d.x))
      .attr('cy', (d) => yScale(d.y))
      .attr('r', 0)
      .attr('fill', '#FBBC05')
      .attr('stroke', 'rgba(56, 8, 228, .5)')
      .transition()
      .duration(300)
      .attr('r', 8)

1.gif

  • 创建绘制组(g),所有的点都绘制在组内。
  • 给每个点添加标识,用于后面操作。通过比例尺获取点在坐标轴中的位置。
  • 设置加载动画,点由小变大。

添加交互

    var tooltips = d3
      .select('body')
      .append('div')
      .style('width', '130px')
      .style('height', '20px')
      .style('background-color', '#fff')
      .style('dispaly', 'flex')
      .style('justify-content', 'center')
      .style('padding', '10px')
      .style('border-radius', '5px')
      .style('opacity', 0)

    d3.selectAll('.point')
      .on('mouseenter', (e, g) => {
        tooltips
          .html(`X:${g.x} , Y:${g.y}`)
          .style('position', 'absolute')
          .style('left', `${e.clientX}px`)
          .style('top', `${e.clientY}px`)
          .style('opacity', 1)
      })
      .on('mouseleave', (e, g) => {
        tooltips.style('opacity', 0).style('left', `0px`).style('top', `0px`)
      })

2.gif

  • 创建提示框。通过标识符.point获取所有的点。根据鼠标监听事件来设置对应的数据和位置。
  • 代码地址