1说明
i、js用的是raphael(绘制图形),jquery(主要get到json)
ii、设计初衷是做后台管理的导航地图,也基本实现这个功能
iii、json里面主要2个key,一个是name,一个是children,如果想要额外功能,比如跳转指定网址,请加参数,并在click方法内添加
2显示效果
3传入json
{ "name": "a", "children": [ { "name": "a1", "children": [ { "name": "a11", "children": [ { "name": "a111" }, { "name": "a112" }, { "name": "a117", "children": [ { "name": "a1171" }, { "name": "a1172" }, { "name": "a1173" } ] } ] }, { "name": "a12" } ] } , { "name": "a2", "children": [ { "name": "a21" }, { "name": "a22" , "children": [ { "name": "a221" }, { "name": "a222" } ] } ] } , { "name": "a3", "children": [ { "name": "a31" } ] } , { "name": "a4", "children": [ { "name": "a41" }, { "name": "a42" } ] } ] }
4下面是代码
DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Raphael Testtitle>
head>
<body>
<div id="my-canvas" style="width:140px;padding:0px;margin:0px;">div>
<span id="ruler" style="visibility: hidden; white-space: nowrap; font-size: 10px; ">span>
<script type="text/javascript" src="raphael.js">script>
<script type="text/javascript" src="jquery.js">script>
<script type="text/javascript">
String.prototype.visualLength = function() {
var ruler = $("#ruler");
ruler.text(this);
return ruler[0].offsetWidth;
} ;
var mindmap = function(id, width, height, data) {
var leftY = 0;
//左侧初始高度(系统自动计算)
var rightY = 0;
//右侧初始高度 (系统自动计算)
var unitWidth = 50;
//每个文本的宽度(手工改)
var unitHeight = 16;
//每个文本的高度(手工改)
var xAdd = 230;
//x坐标偏移量(手工改)默认中心位置在(0,0),只能显示1/4图片,就是x,-y象限,需要把图片往右下方移动才能看到全貌
var yAdd = 00;
//y坐标偏移量(手工改)
var xRate = 70;
//x比例系数(手工改)用于放大内容
var yRate = 50;
//y比例系数(手工改)
var lineColor = ["yellow", "FF00AC", "green", "red", "F3B1A0"];
//线条颜色
var colorIndex = 0;
//对象1继承对象2的内容
var extend = function(destination, source) {
for (var property in source)
destination[property] = source[property];
return destination;
};
//计算孩子节点的数量
//children是孩子部分
//size是内部数量
//isRight=true表示在右边
//level表示第几层级
//thick表示深度
var countChildrenSize = function(data, level, isRight, depth) {
var size = 0;
//有几个孩子
var leftSize = 0;
//左侧总高度
var rightSize = 0;
//右侧总高度
var thick = 0;
//深度
var leftThick = 0;
//左侧总高度
var rightThick = 0;
//右侧总高度
if (data["children"] != null && data["children"].length > 0) {//如果没有孩子节点,则自己设为0,返回0
for (var i = 0; i < data["children"].length; i++) {
var right = isRight != null ? isRight : (i % 2 == 0);
var count = countChildrenSize(data["children"][i], level + 1, right, depth + 1);
size += count.size;
if (thick < count.thick) {
thick = count.thick;
};
if (right) {
rightSize += count.size;
if (rightThick < thick) {
rightThick = thick;
};
} else {
leftSize += count.size;
if (leftThick < thick) {
leftThick = thick;
};
}
}
thick++;
} else {
size = 1;
thick = 1;
}
extend(data, {
depth : depth,
size : size,
level : level,
thick : thick
});
if (isRight != null) {
data.isRight = isRight;
};
return {
size : size,
thick : thick,
rightSize : rightSize,
leftSize : leftSize,
rightThick : rightThick,
leftThick : leftThick,
};
};
//计算位置,json,左边深度,右边深度
var countPos = function(data, rightThick, leftThick) {
var width;
var height;
if (data["children"] != null && data["children"].length > 0) {
var sumHeight = 0;
for (var i = 0; i < data["children"].length; i++) {
var pos = countPos(data["children"][i], rightThick, leftThick);
sumHeight += pos.height;
}
height = sumHeight / data["children"].length;
} else {
if (data.isRight) {
rightY = rightY + 1;
height = rightY;
} else {
leftY = leftY + 1;
height = leftY;
}
}
if (data.isRight == null) {
width = 0;
} else if (data.isRight) {
width = data.depth;
} else {
width = -data.depth;
}
;
var pos = {
width : width,
height : height
};
extend(data, pos);
return pos;
};
//数据,绘图,父节点
var draw = function(data, paper, parentData) {
if (parentData != null) {//线条颜色
data.color = parentData.color == null ? lineColor[colorIndex++] : parentData.color;
}
if (data["children"] != null && data["children"].length > 0) {
for (var i = 0; i < data["children"].length; i++) {
draw(data["children"][i], paper, data);
}
}
var posX = xAdd + xRate * data.width;
var posY = yAdd + yRate * data.height;
//和上级的连接曲线
if (parentData != null) {
var _posX = xAdd + xRate * parentData.width;//父节点的x
var _posY = yAdd + yRate * parentData.height;//父节点的y
var start = data.isRight ? {
x : posX,
y : posY + unitHeight / 2
} : {
x : posX + unitWidth,
y : posY + unitHeight / 2
};//起始点
var end = data.isRight ? {
x : _posX + unitWidth,
y : _posY + unitHeight / 2
} : {
x : _posX,
y : _posY + unitHeight / 2
};//结束点
var cut1 = {
x : end.x,
y : start.y
};
var cut2 = {
x : start.x,
y : end.y
};
//曲线连接
paper.path("M" + start.x + " " + start.y + " C" + cut1.x + " " + cut1.y + " " + cut2.x + " " + cut2.y + " " + end.x + " " + end.y).attr('stroke', data.color);
//直线连接
//paper.path("M"+(posX+unitWidth)+" "+(posY+unitHeight/2)+"L"+(_posX)+" "+(_posY+unitHeight/2)).attr("stroke",data.color);
//下划线
paper.path("M" + posX + " " + (posY + unitHeight / 2) + "L" + (posX + unitWidth) + " " + (posY + unitHeight / 2)).attr("stroke", data.color);
}else{//第一个主题,加框
paper.rect(posX,posY- unitHeight / 2,unitWidth,unitHeight,2);
};
//paper.rect((xAdd + xRate * data.width),( yAdd + yRate * data.height),(xAdd + xRate * data.width+unitHeight),( yAdd + yRate * data.height+unitHeight),10).attr("fill","yellow");
var len = data.name.visualLength();
//主体文本
var text = paper.text(xAdd + xRate * data.width+(unitWidth-len)/2, yAdd + yRate * data.height, data.name);
text.attr({
"fill" : "dodgerblue",
"font-size" : "10px",
"text-anchor" : "start",
});
text.click(function() {
alert(data.name);
window.open('http://www.baidu.com');//可以用作导航,打开页面
});
};
//初始化图形
var init = function(data) {
var paper = Raphael(id, width, height);
//计算孩子辅助数据
var count = countChildrenSize(data, 1, null, 0);
console.info(count);
var difference = Math.floor(Math.abs(count.rightSize - count.leftSize) / 2);
//左右起始高度差
if (count.rightSize > count.leftSize) {//初始化第一个位置
leftY += difference;
};
//计算叶子相对位置
countPos(data, count.rightThick, count.leftThick);
draw(data, paper);
console.info(JSON.stringify(data));
};
//at last
init(data);
};
$.ajax({
url : "a.json",
data : {
t : new Date().getTime()
},
dataType : "json",
success : function(data) {
mindmap("my-canvas", 800, 500, data);
}
});
script>
body>
html>