持续创作,加速成长!这是我参与「掘金日新计划 · 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')
.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)
- 创建绘制组(
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`)
})
- 创建提示框。通过标识符
.point
获取所有的点。根据鼠标监听事件来设置对应的数据和位置。 - 代码地址