D3.js

D3.js力导向图(节点+连线+连线文字+节点文字)

json文件格式

{
"nodes":[
	{"id":"1","name":"北京大学","ntype":"school"},
	{"id":"2","name":"软件工程","ntype":"special"}],
"links": [
	{"target":"1","source":"2","name":"专业","type":"special_link"}
]

具体代码

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>       
    </style>
</head>

<body>
    <script src="js/d3.min.js"></script>
    <script>
		const nodeConf = {
    fillColor: {
        school: 'rgb(255, 76, 10)',
        special: '#00FF33',
		A:'rgb(220,20,60)'
    },
    strokeColor: {
        school: '#993300',
        special: 'rgb(35, 148, 206)',
		H:'rgb(255,240,245)'
    },
    strokeWidth: {
        school: 3,
        special: 3,
		C:3
    },
    textFillColor: {
        school: 'black',
        special: 'black',
		C:'black'
    },
    radius: {
        school: 6,
        special: 16,
		C:25
    }
};

const lineConf = {
    strokeColor: {
        
        special_link: 'rgb(204, 225, 152)',
        INVEST_C: 'rgb(242, 90, 41)'
    }
};
		
var width = 2000,
	height = 900;


var svg = d3.select("body").append("svg")
	.attr("width", width)
	.attr("height", height);

var force = d3.layout.force() // - 使用物理模拟排放链接节点的位置
	.size([width, height])
	.charge(-100) // 取得或者设置电荷强度
	.linkDistance(180);

d3.json("data2.json", function (error, graph) {
	if (error) throw error;
	var edges = [];
	graph.links.forEach(
		function (e) {
			var sourceNode = graph.nodes.filter(function (n) {
					return n.id === e.source;
				})[0],
				targetNode = graph.nodes.filter(
					function (n) {
						return n.id === e.target;
					})[0]

			edges.push({
				source: sourceNode,
				target: targetNode,
				name:e.name,
				type:e.type
			});
		}
	);
	force
		.nodes(graph.nodes) // 取得或者设置布局的节点数组
		.links(edges) // 取得或者设置节点间的链接数组
		.on("tick", tick) // 监听在计算布局位置时的更新  执行tick函数
		.start(); // 当节点变化时启动或者重启模拟

	


	// line    
	var link = svg.selectAll(".link")
		.data(edges)
		.enter().append("path")
		.attr({
			'd': function (d) {
				return 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target
					.y
			},
			'class': 'edgepath',
			'id': function (d, i) {
				return 'edgepath' + i;
			}
		})
		.style('stroke', link => lineConf.strokeColor[link.type])
		.style('stroke-width', 1)
		

		
		

	// 线上文字

	var edges_text = svg.selectAll(".edgelabel")
		.data(edges)
		.enter()
		.append("text")
		.attr({
			'class': 'edgelabel',
			'id': function (d, i) {
				return 'edgepath' + i;
			},
			'dx': 80,
			'dy': 0
			//'font-size':10,
			//'fill':'#aaa'
		})
	//设置线条上的文字
	edges_text.append('textPath')
		.attr('xlink:href', function (d, i) {
			return '#edgepath' + i
		})
		.style("pointer-events", "none")
		.text(function (d) {
			return d.name;
		});

	//  node
	var node = svg.selectAll(".node")
		.data(graph.nodes)
		.enter().append("g")
		.attr("class", "node")
		.call(force.drag); // 为当前选择调用一个函数。  给节点绑定拖动行为

	node.append("circle") // 设置圆圈的样式
		.attr("r",  node => nodeConf.radius[node.ntype])
		.style("fill", node => nodeConf.fillColor[node.ntype])
		.style('stroke', node => nodeConf.strokeColor[node.ntype])
		

	node.append("text")
		.attr("dy", ".35em")
		.attr("text-anchor", "middle") // 文本锚点属性被用来描述该文本与所给点的对齐方式 (开头、中间、末尾对齐) 。
		.text(function (d) { // 确定节点的文字
			return d.name;
		}).style('fill', node => nodeConf.textFillColor[node.ntype])
		.style("font-size",10);
		
		//鼠标交互
		 


	function tick() {
		// 更新线
		link.selectAll("line")
			.attr("x1", function (d) {
				return d.source.x;
			})
			.attr("y1", function (d) {
				return d.source.y;
			})
			.attr("x2", function (d) {
				return d.target.x;
			})
			.attr("y2", function (d) {
				return d.target.y;
			});


		link.attr('d', function (d) {
			var path = 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target
				.y;
			return path;
		});

		edges_text.attr('transform', function (d, i) {
			if (d.target.x < d.source.x) {
				bbox = this.getBBox();
				rx = bbox.x + bbox.width / 2;
				ry = bbox.y + bbox.height / 2;
				return 'rotate(180 ' + rx + ' ' + ry + ')';
			} else {
				return 'rotate(0)';
			}
		});

		// 更新节点
		node.attr("transform", function (d) {
			return "translate(" + d.x + "," + d.y + ")";
		});

	}
});
	
    </script>
</body>

</html>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值