因为自己想要写点东西,所以学习了d3
现在前端已经不再是jQuery的时代了,所以切换到了vue + vue-router + vuex全家桶
d3有很多教程,这里记录的主要是其他教程没有的东西,也是我在实践中踩过的坑,记录下来就不怕忘了
这是一个用d3在vue中绘制一个曲线图,然后通过拖拽曲线图上的标记点,改变曲线的形状,所以需要用到symbol
从d3的v5版本起,d3内部各个模块被拆分,在使用时可以分别导入以缩减最终生成的文件的体积,减少网络传输负担,所以以前的老版本是d3.line().type(symboltype),现在不用了,可以直接用d3.symbol().type(symboltype)
默认情况下,所有的symbol位置都在原点,也就是svg的左上角,如果想要把symbol移动到设定的位置,需要加上
.attr('transform', (d) => `translate(${d[0]},${d[1]})`)
这里使用了es6的字符串表达式,表达式的两侧不是单引号,而是键盘上1左边那个键,和波浪线在一起
另外,为了将来和drag配合,我这里特意为每一个节点添加了linenum和pointnum属性,用的时候可以用
.attr('linenum')
读出来
代码中包含了this,这是因为这是vue单文件组件的一部分,这里的this指的是上下文组件,this里的数据是在vue的data里面定义的
drawSymbols (points) {
let [p, tempx, tempy] = [[], null, null]
for (let i = 0; i < points.length; i++) {
for (let j = 0; j < points[i].length; j++) {
tempx = this.axises.xScale(points[i][j][0])
tempy = this.axises.yScale(points[i][j][1])
p.push([tempx, tempy])
}
}
let symbolGenerator = d3.symbol()
.size(70)
.type(d3.symbolCircle)
this.symbols.node.selectAll('path')
.data(p)
.enter()
.append('path')
.attr('d', symbolGenerator)
.attr('id', (d, i) => 'symbol' + i)
.attr('linenum', (d, i) => Math.floor(i / this.$store.state.lineControlPoints[0].length))
.attr('pointnum', (d, i) => i % this.$store.state.lineControlPoints[0].length)
.attr('stroke', '#FF0000')
.attr('stroke-width', '2px')
.attr('fill', 'white')
.attr('transform', (d) => `translate(${d[0]},${d[1]})`)
.exit().remove()
},