功能
这是一个用js写的简易思维脑图,大约用了100多行代码,效果如下图
有的功能
- 只能把数据展示成思维脑图!
- 可自定义字体颜色、边框颜色、边框背景、连线颜色!
没有的功能
- 不能编辑!
- 不能缩放!
- 不能展开收缩!
差什么功能小伙伴们可以自行DIY一下,后期可能会补足这些功能!
对mvvm框架的支持
我为公司改过一版适用angular框架的,受限于angular render2,我在代码中用了几个setTimeout(),感觉很不优雅,就不提供给小伙伴了。
纯洁的js代码,小伙伴可以DIY给 angular
react
vue
框架!
原理
详见下面代码和代码注释
// typeScript 数据格式
// class Node {
// title: string;
// children: [Node];
// fontColor?: string = null;
// borderColor?: string = null;
// bgColor?: string = null;
// }
// mack 数据
const treeData = [
{
title: '张海生',
children: [
{
title: "1.1",
children: [
{title: "1.1.1"},
{
title: "李1.1.2光",
children: [
{title: "张1.1.2.1中"},
{title: "1.1.2.2"},
{
title: "1.1.2.3",
children: [
{title: "1.1.2.3,1"},
{title: "1.1.2.3.2"},
{title: "1.1.2.3.3"},
{title: "1.1.2.3.4"},
{title: "1.1.2.3.5"},
]
},
{title: "1.1.2.4"},
{title: "1.1.2.5"},
]
},
]
},
{
title: "1.2",
children: [
{title: "1.2.1",borderColor:"red",fontColor:"red"},
{title: "1.2.2",bgColor:"black",fontColor:"white"},
]
},
]
}
];
const nodeFontS = 14; // 字体大小
const interval = 25; // 节点左右间隔大小
const padding = 4; // 节点内部padding
const margin_y = 6; // 节点上下margin
const fontColor = "#626262"; // 默认字体颜色
const borderColor = "#55aaee"; // 默认边框颜色
const lineColor = "#55aaee"; // 默认连线颜色
const svg = document.getElementById('svgContainer');
let _svgW = 0;
let _lastNodeN = 0;
const _nodeH = nodeFontS + padding * 2 + margin_y * 2;
// 树状结构数据重构
reBuildData(treeData, null);
buildSvg(treeData);
setSvgContainerSize(_svgW+30, _lastNodeN * _nodeH + 30);
console.log('treeData');
console.log(treeData);
console.log(_lastNodeN);
function reBuildData(d, parent) { //树状结构数据重构
d.forEach((v, i) => {
v.parent = parent;
if (v.children && v.children.length > 0) {
reBuildData(v.children, v);
parentY(v, d.length, i)
} else {
_lastNodeN = _lastNodeN + 1;
v.y = _lastNodeN;
parentY(v, d.length, i)
}
})
}
function parentY(lastNode, len, i) { //计算节点的y坐标
const parent = lastNode.parent;
if (len === (i + 1) && !!parent) {
const s = parent.children[0].y;
parent.y = s + (lastNode.y - s) / 2
}
}
function setSvgContainerSize(w, h) { //设置svg的宽和高
svg.setAttribute("width", w);
svg.setAttribute("height", h);
}
function buildSvg(data) { //生成脑图svg
data.forEach((v) => {
buildNode(v);
if (!!v.children && v.children.length > 0) {
buildSvg(v.children)
}
})
}
function buildNode(node) { // 构建脑图的每个节点
const gTag = document.createElementNS('http://www.w3.org/2000/svg', 'g');
const textTag = document.createElementNS('http://www.w3.org/2000/svg', 'text');
const text = document.createTextNode(node.title);
textTag.appendChild(text);
gTag.appendChild(textTag)
svg.appendChild(gTag);
textTag.setAttribute("fill", node.fontColor ? node.fontColor : fontColor);
const parentx = !!node.parent ? node.parent.x : 0;
const parentw = !!node.parent ? node.parent.w : 0;
const intervalNow = !!node.parent ? interval : 0;
const textH = Math.ceil(textTag.getBBox().height);
node.w = Math.ceil(textTag.getBBox().width) + padding * 2;
node.x = parentx + parentw + intervalNow + 6;
gTag.setAttribute('transform', `translate(${node.x + padding},${node.y * (_nodeH) + textH / 2 - 5})`);
if ((node.w + node.x) > _svgW) {
_svgW = node.w + node.x;
}
gTag.insertBefore(drawBorder(node), textTag);
drawLine(node);
}
function drawBorder(node){ //画节点的边框
const fan = document.createElementNS('http://www.w3.org/2000/svg', 'path');
fan.setAttribute("d", getBorderD(node));
fan.setAttribute('stroke', node.borderColor ? node.borderColor : borderColor);
fan.setAttribute("stroke-width", "1");
fan.setAttribute("fill", node.bgColor?node.bgColor:"none");
return fan;
}
function getBorderD(node){ //获得节点的d
return `M0,-17h${node.w-8}a5,5,0,0,1,5,5v13a5,5,0,0,1,-5,5h-${node.w-8}a5,5,0,0,1,-5,-5v-13a5,5,0,0,1,5,-5z`
}
function drawLine(node) { //为当前节点连线父级节点
if (!node.parent) {
return
}
const fan = document.createElementNS('http://www.w3.org/2000/svg', 'path');
svg.appendChild(fan);
fan.setAttribute("d", getD(node));
fan.setAttribute('stroke', lineColor);
fan.setAttribute("stroke-width", "1");
fan.setAttribute("fill", "none");
}
function getD(node) { // 获得节点的 d线
const parent = node.parent;
if (parent.y != node.y) {
return `M${parent.x + parent.w} ${parent.y * _nodeH} C${parent.x + parent.w + 15} ${parent.y * _nodeH} ${node.x - 15} ${node.y * _nodeH} ${node.x} ${node.y * _nodeH}`;
} else {
return `M${parent.x + parent.w} ${parent.y * _nodeH} L${node.x} ${node.y * _nodeH}`;
}
}
源码
复制过来很多字符前面被segmentfault加了转译字符,我手动删除了,可以会误删,要看源码可以去我GitHub上clone
github源码 https://github.com/sure2darli...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。