vue+D3 基于path的力导向图

<template>
    <div id="login">
       
        <ul>
  <li><a class="active" href="https://tv.cctv.com/2012/12/03/VIDA1354512311612143.shtml">亮剑介绍</a></li>
  <li><a href="https://www.tvmao.com/drama/LW5SVw==/actors">人物简介</a></li>
  <li><a href="https://m.tvmao.com/mip_drama/LW5SVw==/actors">数据来源</a></li>
  <li><a href="https://tv.cctv.com/2015/08/27/VIDE1440638136134698.shtml?spm=C55853485115.Pbqb0ldQ5nlz.0.0">在线观看</a></li>
</ul>
    </div>
    <div id="force-container">
      <h1  ><a href="https://www.tvmao.com/drama/LW5SVw==/actors">《亮剑》主要人物关系图</a></h1>
  <h5 >20数科</h5>
    </div>
</template>

<style>
ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  width: 200px;
  background-color: #f1f1f1;
  border: 1px solid #555;
}

li a {
  display: block;
  color: #000;
  padding: 8px 16px;
  text-decoration: none;
}

li {
  text-align: center;
  border-bottom: 1px solid #555;
}

li:last-child {
  border-bottom: none;
}

li a.active {
  background-color: #061d07;
  color: white;
}

li a:hover:not(.active) {
  background-color: #555;
  color: white;
}
        #login {
  background: url("F:\vite-vue\public\image\mu.jpg") no-repeat;
  background-position: center;
  height: 100%;
  color: black;
  width: 100%;
  background-size: cover;
  position: fixed;
  opacity: 0.7;
}

			.tooltip{  
				position: absolute;  
				width: 200px;  
				height: auto;  
				font-family: simsun;  
				font-size: 7px;
				text-align: left;  
				color: black;  
				border-width: 1px solid black;  
				background-color: 7FFF00;  
				border-radius: 2px;  
			}  
			.tooltip:after{   
				content: '';  
				position: absolute;  
				bottom: 100%;  
				left: 20%;  
				margin-left: -3px;  
				width: 0;  
				height: 0;  
				border-bottom: 12px solid black;  
				border-right: 12px solid transparent;  
				border-left: 12px solid transparent;  
			}  
	</style>  
<script>
import { defineComponent } from 'vue';
//import axios from "axios";
import * as d3 from "d3";

var color=d3.schemeCategory10;

   var nodes= [{"name":"李云龙","image":"liyunlong.jpg","intro":"曾在红四方面军任团长,八路军时任129师直属独立团团长。解放战争时任中原野战军新二师师长。解放后调任福建省军区某海防军军长。1955年去南京军事学院学习,毕业后继续担任该军军长授少将衔"},
            {"name":"赵刚","image":"zhaogang.jpg","intro":"曾是燕京大学学生,为人坦率,是个典型的理想主义者。1937年加入中国共产党,在延安抗大学习,1938年任八路军129师386旅独立团政治委员,与李云龙一路磕磕碰碰可仍然相处默契。淮海战役期间任华东野战军11纵2师政治委员、2纵副政委兼纵队政治部主任,1955年被授予少将军衔。"},
            {"name":"孔捷","image":"kongjie.jpg","intro":"性情暴烈,资历深,因为在朝鲜战争中的磨练,对国防现代化有着深刻的认识,原四方面军出身,后来属东北四野9纵26师师长,1950年任46军副军长,随后1951年入朝作战,1952年升任军长,1954年在南京军事学院战役系当学员,1955年授少将。"},
            {"name":"丁伟","image":"dingwei.jpg","intro":"热血战将,具有远大的战略眼光和天才的战术指挥,虽然与李云龙、孔捷相比资历稍浅,但军事才能绝不下于他们。在抗日战争期间他任28团团长、129师新编第一团团长,参加了晋西北混战,负责打援任务。"},
            {"name":"魏大勇","image":"heshang.jpg","intro":"原中央军七十二师士兵,忻口会战时负伤被日军俘虏,后加入八路军386旅独立团任政委赵刚警卫员,后任团长李云龙的警卫员。骁勇善战,后惨死于黑云寨土匪手中。"},
            {"name":"张大彪","image":"zhangdabiao.jpg","intro":"张大彪原是国民革命军第29军中尉副连长,在南苑一战受了伤,跟部队走散。后来遇见李云龙,被收入麾下,又提拔他为营长,跟沈泉同级。后来李云龙又升任他为团参谋长。解放战争初期,张大彪的身份是华野二师参谋长,依然跟随李云龙。"},
            {"name":"孙德胜","image":"sundesheng.jpg","intro":"担任八路军386旅独立团骑兵连连长,是团长李云龙颇为看重的虎将。"},
            {"name":"刑志国","image":"xingzhiguo.jpg","intro":"独立团副团长,是李云龙的老战友"},
            {"name":"段鹏","image":"duanpeng.jpg","intro":"李云龙属下,身手与魏大勇和尚不相上下。"},
            {"name":"筱冢义男","image":"xiaozhongyinan.jpg","intro":"日本在晋西北最高司令官,中将军衔"},
            {"name":"山本一木","image":"shanben.jpg","intro":"大佐军衔。听命于华北派遣军第一军司令长官筱冢义男。"},
            {"name":"朱子明","image":"zhuziming.jpg","intro":"独立团警卫排排长,后被日军俘虏。成为汉奸。并帮助日军劫走杨秀芹"},
            {"name":"杨秀芹","image":"yangxiuqin.jpg","intro":"李云龙第一任妻子,在新婚之夜被山本一木突袭劫走。后在平安一战中被李云龙下令开炮与日本人一起死亡"},
            {"name":"常乃超","image":"changnaichao.jpg","intro":"国民党军队将领,后在战争中被李云龙俘虏。后成为中共一员"},
            {"name":"楚云飞","image":"cuyunfei.jpg","intro":"国民党将领,黄埔5期毕业生。在抗日的时候,曾与八路军协同作战,那时在多次与李云龙配合交手的过程中,他对李云龙产生了敬佩之情。但是敬佩归敬佩,在后来国共开战两人成为敌人之后,他们又多次在战场上血光相见,彼此都是毫不留情地要把对方彻底消灭。解放之后楚云飞随国民党去了台湾。"},
            {"name":"田雨","image":"tianyu.jpg","intro":"李云龙第二任妻子田雨,出身于一个名门望族的知识分子家庭,独生女的她读书时离家出走参加解放军。当了一名护士,在照顾负伤的李云龙期间因仰慕李云龙而嫁给了李云龙。"},
            {"name":"冯楠","image":"fengnan.jpg","intro":"赵刚的妻子,田雨的好朋友,北京大学讲师。在李云龙夫妇的介绍下与赵刚结婚,对丈夫的工作十分支持。和赵刚育有四名子女。当丈夫遭到迫害的时候给予很大帮助,后来托人将自己的孩子交给李云龙抚养。文革中遭受迫害陪伴丈夫一起自杀"},
            {"name":"张白鹿","image":"bailu.jpg","intro":"张白鹿是田雨的大学同学,因为仰慕李云龙的英雄气质而喜欢上了对方"},
            {"name":"罗万春","image":"luowanchun.jpg","intro":"罗万春是医院政治处主任,喜欢给人张罗介绍对象,有时候处在中间两头受气"},
            {"name":"田墨轩","image":"tianmoxuan.jpg","intro":"田雨父亲,高级知识分子家庭。是出名的文学家"},
            {"name":"沈丹虹","image":"shendanhong.jpg","intro":"田雨母亲,"},
            {"name":"谢宝庆","image":"xiebaoq.jpg","intro":"谢宝庆本是黑云寨的大当家的,孔健本想收编他,但因谢宝庆手下杀害李云龙警卫员魏大勇,李云龙一怒之下踏平黑云寨"},
            {"name":"山猫","image":"shanmao.jpg","intro":"偷袭杀害和尚魏大勇,后被李云龙亲手砍了脑袋"}
        ];
       var links=[{"source":0,"target":1,"value":"政委&挚友"},
            {"source":0,"target":2,"value":"老战友"},
            {"source":0,"target":3,"value":"老战友"},
            {"source":0,"target":4,"value":"战友&警卫员"},
            {"source":0,"target":5,"value":"战友&属下"},
            {"source":0,"target":6,"value":"骑兵连连长"},
            {"source":0,"target":7,"value":"副团长"},
            {"source":0,"target":8,"value":"战友&属下"},
            {"source":0,"target":9,"value":"敌人"},
            {"source":0,"target":10,"value":"敌人"},
            {"source":0,"target":12,"value":"第一任妻子"},
            {"source":0,"target":13,"value":"俘虏"},
            {"source":0,"target":14,"value":"好友"},
            {"source":0,"target":15,"value":"第二任妻子"},
            {"source":0,"target":17,"value":"爱慕"},
            {"source":0,"target":19,"value":"老丈人"},
            {"source":0,"target":20,"value":"丈母娘"},
            {"source":0,"target":21,"value":"剿匪"},
            {"source":21,"target":22,"value":"属下"},
            {"source":1,"target":16,"value":"妻子"},
            {"source":2,"target":3,"value":"老战友"},
            {"source":15,"target":16,"value":"好友"},
            {"source":15,"target":17,"value":"好友&情敌"},
            {"source":16,"target":17,"value":"好友"},
            {"source":15,"target":18,"value":"医院主任"},
            {"source":15,"target":19,"value":"父亲"},
            {"source":15,"target":20,"value":"母亲"},
            {"source":22,"target":4,"value":"杀害"},
            {"source":9,"target":10,"value":"上司"},
            {"source":10,"target":12,"value":"杀害"},
            {"source":10,"target":11,"value":"汉奸"},
            {"source":13,"target":14,"value":"国军友军"}];
export default defineComponent({
    mounted() {      
        this.drawBarChart(nodes,links);      
    },
    methods:{
        drawBarChart(nodes,links){
            var  img_h=50;
		    var  img_w=50;
		    var  radius=10;
            var w=window.innerWidth|| document.documentElement.clientWidth|| document.body.clientWidth;
			var h=window.innerHeight|| document.documentElement.clientHeight|| document.body.clientHeight;
			w=w*0.98;
			h=h*0.9;
           //提示框定义
            let tooltip = d3.select('body')
					.append('div')
					.style('position', 'absolute')
					.style('z-index', '25')
					.style('color', 'black')
					.style('visibility', 'hidden')   
					.style('font-size', '20px')
					.style("background-color","white")
					.style("opacity",1.0)
					.style("stroke-width",2)
					.style("border-radius", "10px");
            var svg=d3.select("#force-container")
                        .append("svg")
                        .attr("width",w)
                        .attr("height",h*1.8);
            var forceSimulation = d3.forceSimulation()
                                    .force("link",d3.forceLink())
                                    .force("charge",d3.forceManyBody().strength(-800))
                                    .force("center",d3.forceCenter(w/2,h/2));
            forceSimulation.nodes(nodes)
                           .on("tick");
            forceSimulation.force("link")
                           .links(links)
            var path = svg.selectAll("path")
				          .data(links)
			              .enter()
						  .append("path")
				          .attr("id", function(d,i) {
						       return "links" +i;
				          })
				         .attr("class","links");
             
            var link=svg.selectAll(".link")
                        .data(links)
                        .enter()
                        .append("line")
                        .attr("class","link")
                        .style("stroke-width",1)
                        .style("stroke",(d,i)=>color[i%10])
					    .style("opacity",0.6);
                        var  img_h=50;
		var  img_w=50;
		var  radius=18;
            var node=svg.selectAll(".node")
                        .data(nodes)
                        .enter()
                        .append("circle")
                        .attr("r",18)
                        .style("stroke","DarkGray")
				   .style("stroke-width","1.0px")
				   .attr("fill", function(d, i){
                                    //创建圆形图片
                                    var defs = svg.append("defs").attr("id", "imgdefs");
                                    var catpattern = defs.append("pattern")
                                                         .attr("id", "catpattern" + i)
                                                         .attr("height", 1)
                                                         .attr("width", 1);
                                    catpattern.append("image")
                                            .attr("x", - (img_w / 2 - radius+5.8))
                                            .attr("y", - (img_h / 2 - radius+3.5))
                                            .attr("width", img_w+11)
                                            .attr("height", img_h+6)
                                            .attr("xlink:href","image/"+d.image);
                                    return "url(#catpattern" + i + ")";
                    })
                        .attr("info",(d)=>d.intro)//新增属性
				   .on("mouseenter",function(d,i){ 
						const node=d3.select(this);
				
					    var t=node.attr("info");//新增属性的信息
						
						tooltip.html(t)
						.style('visibility', 'visible')
						;
						
					})
				.on('mousemove', function (d, i) {
						const node=d3.select(this);

					    var t=node.attr("info");
						tooltip.html(t)
						.style('top', (event.pageY-10)+'px')
						.style('left',(event.pageX+10)+'px');
					})
				.on('mouseout', function (d, i) {
						return tooltip.style('visibility', 'hidden')
					})

                        .call(drag()); 
            forceSimulation.on("tick",()=>{
                link.attr("x1",d=>d.source.x)
                    .attr("y1",d=>d.source.y)
                    .attr("x2",d=>d.target.x)
                    .attr("y2",d=>d.target.y);
                node.attr("cx",d=>d.x)
                    .attr("cy",d=>d.y);
                edges_text.attr("x",d=>(d.source.x + d.target.x) / 2 )
					.attr("y",d=>(d.source.y + d.target.y) / 2 );
                texts.attr("x",d=>d.x)
					 .attr("y",d=>d.y);
            });
            function drag()
            {
                function dragstarted(event,d){
                    if(!event.active)   forceSimulation.alphaTarget(0.3).restart();
                    d.fx=d.x;
                    d.fy=d.y;
                }
                function dragged(event,d){
                    d.fx=event.x;
                    d.fy=event.y;
                }
                function dragended(event,d){
                    if(!event.active)   forceSimulation.alphaTarget(0);
                    d.fx=null;
                    d.fy=null;
                }
                return d3.drag()
                         .on("start",dragstarted)
                         .on("drag",dragged)
                         .on("end",dragended);
            };
            var edges_text = svg.selectAll(".linetext")
							.data(links)
							.enter()
							.append("text")
							.attr("class","linetext")
							.text(d=> d.value)
							.style("stroke",(d,i)=>color[i%10])
							.style("font-size",10);
            
        var  img_h=50;
		var  img_w=50;
		var  radius=26;								
    var pathtext = svg.selectAll('g')
				              .data(links)
				              .enter()
							  .append("text")
							  .append('textPath')
							  .attr("text-anchor", "middle")//居中
						      .attr("startOffset","50%")
							  .attr('xlink:href', function(d,i) { return "#links" + i; })
							  .text(function(d) { return d.value; });
    var texts=svg.selectAll(".forceText")
          .data(nodes)
				 .enter()
				 .append("text")
				 .attr("class","forceText")
				 .attr("x",function(d){return d.x;})
				 .attr("y",function(d){return d.y;})
				 .style("stroke", "#336666")
				 .style("stroke-family","仿宋")
				 .style("font-size","10px")
                 .attr("dx","-1.5em")
				 .attr("dy","3em")
				 .text(function(d){return d.name;});
            	
			function tick() {
			  path.attr("d", function(d) {
					var dx = d.target.x - d.source.x;//增量
					var	dy = d.target.y - d.source.y;
					return "M" + d.source.x + ","+ d.source.y + "L" + d.target.x + "," + d.target.y;
				  });
			  circle.attr("transform", function(d) {
				return "translate(" + d.x + "," + d.y + ")";
			  });
			  nodetext.attr("x",function(d){return d.x;});
			  nodetext.attr("y",function(d){return d.y;});
			}
        }
    }
})
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值