目录
D3.js绘图工具系列文章总提纲:【传送门】
目的
将d3.js进行实例化,一系列操作放于实例中定义。
初始结构
d3Canvas.js
export default class d3Canvas {
constructor(parentNodeId) {
this.parentNodeId = parentNodeId;
this.svg = reactive({});
this.g = reactive({});
this.currentGraph = ref(null);
this.currentWatch = null;
}
init() {
// 获取父节点
var parentNode = document.getElementById(this.parentNodeId);
if (!parentNode) {
console.error('父节点不存在');
return;
}
// 初始化画布元素
var d3Canvas = document.createElement('div');
d3Canvas.id = 'd3Canvas';
parentNode.appendChild(d3Canvas);
this.svg = this.initD3Canvas();
this.g = this.svg.append("g")
.attr("id", "svg-grid");
}
initD3Canvas() {
// 获取容积
const parentNode = document.getElementById(this.parentNodeId);
const currentWidth = parentNode.clientWidth;
const currentHeight = parentNode.clientHeight;
const d3Canvas = d3
.select('#d3Canvas')
.append("svg")
.attr("id", "svg")
.attr("width", currentWidth)
.attr("height", currentHeight)
.attr("viewBox", "0 0 " + currentWidth + " " + currentHeight);
return d3Canvas;
}
}
相关方法
1、控制画布缩放及平移
// 缩放平移
initZoom(svg) {
var zoom = d3.zoom().scaleExtent([0.3, 10]).on("zoom", (event) => this.zoomed(event, svg));
svg.call(zoom).on("dblclick.zoom", null);
}
zoomed(event, svg) {
// let g = svg.selectAll("g");
this.g.attr("transform", event.transform);
}
调用:
init() {
……
this.initZoom(this.svg);
}
2、添加局部网格背景
createGridBackground() {
this.g.insert("rect", ":first-child")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "url(#grid)");
// 使用网格样式填充 SVG 元素背景
var pattern = this.svg.insert("defs", ":first-child")
.append("pattern")
.attr("id", "grid")
.attr("width", 20)
.attr("height", 20)
.attr("patternUnits", "userSpaceOnUse");
// 添加网格线
pattern.append("path")
.attr("d", "M 20 0 L 0 0 0 20")
.attr("stroke", "lightgray")
.attr("stroke-width", 0.5)
.attr("fill", "none");
}
调用:
init() {
……
this.createGridBackground();
}
3、绘制圆形
// 暂时模拟id
generateUniqueId() {
// 生成随机数作为ID的一部分
// 生成6位长度的随机字符串
const randomPart = Math.random().toString(36).substr(2, 6);
// 获取当前时间戳作为ID的另一部分
// 取最后2位作为时间戳的字符串表示
const timestampPart = new Date().getTime().toString(36).substr(-2);
// 将随机数和时间戳组合成ID
const uniqueId = randomPart + timestampPart;
return uniqueId;
}
drawCircle() {
const _this = this;
let id = this.generateUniqueId();
let circle = this.g.append("circle")
.attr("cx", 50)
.attr("cy", 50)
.attr("r", 20)
.style("fill", "blue")
.attr("id", `circle-${id}`)
}
注:相关绑定事件(点击、拖拽)可通过提纲查看【传送门】