安装D3
npm install d3 --save
首先确认你使用的是vue还是Nuxt
vue
//如果使用的是vue就把代码中的注释解开,再把this.$d3替换成d3
// import * as d3 from "d3";
Nuxt
创建组件mindMap.vue
<template>
<div class="catalogue">
<div class="header">
<p>{
{
objs.course_name }}</p>
<p>{
{
objs.course_name_en }}</p>
</div>
<div class="d3" :style="{ height: `${d3Height + 48}px` }">
<div :id="id" class="d3-content"></div>
</div>
</div>
</template>
<script>
// import * as d3 from "d3";
export default {
props: {
objs: Object,
data: Object,
nodeWidth: {
type: Number,
default: 340,
},
nodeHeight: {
type: Number,
default: 40,
},
active: {
type: String,
default: "",
},
},
components: {
},
data() {
return {
isClient: typeof window !== "undefined",
canvasWidth: 1032,
id: "TreeMap" + randomString(4),
deep: 0,
treeData: null,
show: true,
initWidth: 0,
initHeight: 500,
isPlayBtn: false,
isPlayId: "",
d3Height: 500,
isWidth: 0,
};
},
mounted() {
window.addEventListener("resize", () => {
let el = document.querySelector(".catalogue");
this.canvasWidth = el.offsetWidth;
// if (process.browser) {
// this.$nextTick(() => {
// this.drawMap();
// window.handleCustom = this.handleCustom;
// });
// }
});
if (process.browser) {
this.$nextTick(() => {
let el = document.querySelector(".catalogue");
this.canvasWidth = el.offsetWidth;
this.drawMap();
window.handleCustom = this.handleCustom;
});
}
},
methods: {
drawMap(boo) {
let that = this;
// 源数据
let data = {
};
// 判断data是否为空对象
if (this.data && JSON.stringify(this.data) !== "{}") {
data = this.data;
} else {
data = this.demoData;
}
if (!this.treeData) {
this.treeData = data;
} else {
// 清空画布
this.$d3
.select("#" + this.id)
.selectAll("svg")
.remove();
}
let leafList = [];
getTreeLeaf(data, leafList);
let leafNum = leafList.length;
let TreeDeep = getDepth(data);
// 左右内边距
let mapPaddingLR = 10;
let mapPaddingTB = 0;
// 上下内边距
if (!boo) {
this.initWidth = this.nodeWidth * TreeDeep + mapPaddingLR * 2;
this.initHeight = (this.nodeHeight - 4) * leafNum + mapPaddingTB * 2;
}
let mapWidth = boo
? this.initWidth
: this.nodeWidth * TreeDeep + mapPaddingLR * 2;
// let mapWidth = this.canvasWidth;
let mapHeight = (this.nodeHeight - 4) * leafNum + mapPaddingTB * 2;
this.d3Height = mapHeight < 500 ? 500 : mapHeight;
// 定义画布—— 外边距 10px
let svgMap = this.$d3
.select("#" + this.id)
.append("svg")
.attr("width", mapWidth + 100)
.attr("height", mapHeight < 500 ? 500 : mapHeight)
.style("margin", "0px");
// Zoom functionality
const zoom = this.$d3
.zoom()
.scaleExtent([0.1, 3])
.on("zoom", (event) => {
// svgMap.attr('transform', event.transform);
const transform = event.transform;
const [x, y] = [transform.x, transform.y];
const scale = transform.k;
// Calculate the new transform to keep the tree centered
const centerX = (mapWidth / 2) * scale;
const centerY = (mapHeight / 2) * scale;
const newX = centerX - mapWidth / 2;
const newY = centerY - mapHeight / 2;
svgMap.attr(
"transform",
`translate(${
newX},${
newY}) scale(${
scale})`
);
});
this.$d3
.select("#" + this.id)
.select("svg")
.call(zoom);
// 定义树状图画布
let treeMap = svgMap
.append("g")
.attr(
"transform",
"translate(" +
mapPaddingLR +
"," +
(mapHeight / 2 - mapPaddingTB + 50) +
")"
);
// 将源数据转换为可以生成树状图的数据(有节点 nodes 和连线 links )
let treeData =