## 人物关系知识图谱

#### 一、背景

将结构化数据通过关系预处理程序处理为图数据库可以查询的数据,示例是将其中一部分(人物关系数据)可视化表示。

#### 二、用到的技术

技术点:图数据库Neo4j,d3.js,java,css,spring boot

开发工具:IDEA专业版(可找学生账号注册免费使用一年,社区版不支持WEB开发)

#### 三、项目结构以及代码实现过程

实现思路这样:

1,先定义基础的展示页面index.html

2、完成画图js(graph.js)

3,提供一个基础的拿数据接口加载测试绘图数据和绘图需要的数据(例如节点选中之后的小图标加载)

4、页面从数据接口请求数据之后,调用绘图JS在页面完成画图操作(请求数据的接口可以很方便的改为从图数据库拿取数据进行展示)

主要文件目录说明:

>1、data目录

bg.jpg可视化背景图片数据

CircularPartition.json节点圆形分区图工具栏需要加载的数据

test.json可视化需要展示的数据格式

>2、images

此目录存储节点属性图片数据

>3、js

d3.js version-3.2.8

>4、src

JS以及其它HTML等源码

>5、index.html

知识图谱可视化入口文件

>6、拿数据接口

通过数据Type id加载圆形分区图数据和测试知识图谱构图数据(type等于1加载圆形分区数据,type是等于2加载测试知识图谱展示数据)

GET:http://localhost:7476/knowledge-graph/hello/dataSource/type/{id}

做图过程(graph.js):

```

// 定义画布 (radius是鼠标点击生成圆形分区图的半径)

var width = 1345, height = 750, color = d3.scale.category20();

var svg = d3.select("body")

.append("svg")

.attr("id", "svgGraph")

.attr("width", width)

.attr("height", height)

.append("g")

.attr("id", "svgOne")

.call(d3.behavior.zoom() // 自动创建事件侦听器

.scaleExtent([0.1, 10]) // 缩放允许的级数

.on("zoom", zoom)

)

.on("dblclick.zoom", null); // remove双击缩放

```

```

// 实时获取SVG画布坐标

function printPosition() {

var position = d3.mouse(svg.node());

return position;

}

```

```

// 缩放函数

function zoom() {

// translate变换矢量(使用二元组标识)scale当前尺度的数字

svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); // 画布缩放与移动

// svg.attr("transform", "scale(" + d3.event.scale + ")"); // 画布缩放

}

```

```

// 设置连线箭头属性

function setMarkers() {

svg.append("g")

.attr("id", "lineAndText")

.selectAll("marker")

.data(edges)

.enter()

.append("marker")

.attr("id", function (d) {

return d.id;

})

.attr("viewBox", "0 -5 10 10") // 坐标系的区域

.attr("class", "arrow")

.attr("refX", 27) // refX,refY在viewBox内的基准点,绘制时此点在直线端点上(要注意大小写)

.attr("refY", 0)

.attr("markerWidth", 10) // 标识的大小

.attr("markerHeight", 18) // 标识的大小

.attr("markerUnits", "userSpaceOnUse") // 标识大小的基准,有两个值:strokeWidth(线的宽度)和userSpaceOnUse(图形最前端的大小)

.attr("orient", "auto") // 绘制方向,可设定为:auto(自动确认方向)和 角度值

.append("path")

.attr("d", "M0,-5L10,0L0,5")

.attr("fill", "#ccc");

}

```

```

// 添加连线

function add_edges() {

setMarkers(); // 设置连线箭头属性

var svg_edges = svg.select("#lineAndText")

.selectAll("line")

.data(edges)

.enter()

.append("line")

.attr("id", function (d) {

return d.id;

})

.style("stroke", "#ccc")

.style("stroke_width", 1)

.attr("marker-end", function (d) {

return "url(#" + d.id + ")";

})

.attr("stroke", "#999")

.on("mouseover", function (d) { // 鼠标选中时触发

mouseSelectLine(d);

addToolTip(d); //添加提示框的div

})

.on("mouseout", function () {

d3.select("#relation").remove();

d3.select("#tooltip").remove();

});

return svg_edges;

}

```

```

// 求直线与圆的交点

// 函数参数说明:cx:圆X轴坐标 cy:圆y轴坐标 r:圆半径 stx:起点直线的X轴坐标 sty:起点直线的轴坐标 edx:终点直线的X轴坐标 edy:终点直线的Y轴坐标

// 返回值:交点坐标(x,y)

function getPoint(cx, cy, r, stx, sty, edx, edy) {

// 求直线

var k = (edy - sty) / (edx - stx);

var b = edy - k * edx;

//列方程

var x1, y1, x2, y2;

var c = cx * cx + (b - cy) * (b - cy) - r * r;

var a = (1 + k * k);

var b1 = (2 * cx - 2 * k * (b - cy));

var tmp = Math.sqrt(b1 * b1 - 4 * a * c);

x1 = (b1 + tmp) / (2 * a);

y1 = k * x1 + b;

x2 = (b1 - tmp) / (2 * a);

y2 = k * x2 + b;

// 过滤距离最近的坐标

var p = {};

function lineIf(lx, ly, lxx, lyy) {

var d = Math.sqrt((lx - lxx) * (lx - lxx) + (ly - lyy) * (ly - lyy));

return d;

}

if (cx != stx) { // stx, sty

var d1 = lineIf(x1, y1, stx, sty);

var d2 = lineIf(x2, y2, stx, sty);

if (d1 < d2) {

p.x = x1;

p.y = y1;

} else {

p.x = x2;

p.y = y2;

}

} else { // edx, edy

var d1 = lineIf(x1, y1, edx, edy);

var d2 = lineIf(x2, y2, edx, edy);

if (d1 < d2) {

p.x = x1;

p.y = y1;

} else {

p.x = x2;

p.y = y2;

}

}

return p;

}

```

```

// 鼠标选中关系添加显示效果

function mouseSelectLine(d) {

var p1 = getPoint(d.source.x, d.source.y, 20, d.source.x, d.source.y, d.target.x, d.target.y);

var p2 = getPoint(d.target.x, d.target.y, 20, d.source.x, d.source.y, d.target.x, d.target.y);

var json = [p1, p2];

//构造默认线性生成器

var line = d3.svg.line()

.x(function (d) { //指定x存取器为:取每个数据元素的x属性的值

return d.x;

})

.y(function (d) { //指定y存取器为:取每个数据元素的y属性的值

return d.y;

});

svg.append('path')

.attr({

"d": function () { //生成路径数据

return line(json);

},

"id": "relation"

})

.style({

"stroke": "#87CEFA", //path颜色

"stroke-width": 6 //path粗细

});

}

```

```

// 添加节点

function add_nodes() {

var svg_nodes = svg.append("g")

.attr("id", "circleAndText")

.selectAll("circle")

.data(nodes)

.enter()

.append("g")

.call(force.drag().on("dragstart", function (d) {

d3.select("#eee").remove(); // 删除节点扇形

d3.select("#sel").remove(); // 删除节点选中

d3.event.sourceEvent.stopPropagation(); // 画布拖动与节点拖动分离

d3.select(this).attr("r", 20 * 2);

})

.on("dragend", function (d) {

d3.select("#eee").remove(); // 删除节点扇形

d3.select("#sel").remove(); // 删除节点选中

d.fixed = true; // 拖动结束后节点固定

d3.select(this).attr("r", 20);

})

)

.on("click", function (d) { // 鼠标点击时触发

// 在当前节点处画三页扇形

d3.select("#eee").remove();

drawCirclePartition(d);

})

.on("mouseover", function (d) { // 光标放在某元素上s

mouseSelect(d); // 鼠标选中效果

addToolTip(d); //添加提示框的div

})

.on("mouseout", function (d) {

d3.select("#sel").remove(); // 删除节点选中

d3.select("#tooltip").remove();

d3.select("#tooltipCir").remove();

});

svg_nodes.append("circle")

.attr("id", function (d) {

return d.index;

})

.attr("r", 20)

.attr("fill", function (d, i) {

return color(i);

});

svg_nodes.append("image")

.attr("class", "circle")

.attr("xlink:href", function (d) {

var img = d.image;

if (img != undefined) {

return "http://222.216.195.154:7476/knowledge-graph/path/images/" + d.image

} else {

return null;

}

})

.attr("x", "-20px")

.attr("y", "-20px")

.attr("width", "40px")

.attr("height", "40px");

svg_nodes.append("svg:text")

.style("fill", "#ccc")

.attr("dx", 20)

.attr("dy", 8)

.text(function (d) {

return d.name

});

return svg_nodes;

}

```

```

//添加提示框的div

function addToolTip(d) {

var htmlStr;

if (d.source && d.target && d.type) {

htmlStr = "name:" + d.type + "

";

} else {

htmlStr = "id:" + d.id + "

" + "name:" + d.name + "

";

}

var position = printPosition(d);

var tooltip = d3.select("body").append("div")

.attr("class", "tooltip") //用于css设置类样式

.attr("opacity", 0.0)

.attr("id", "tooltip");

htmlStr = htmlStr + "locx:" + position[0] + "

" + "locy:" + position[1] + "

";

if (d.image != undefined) {

htmlStr = htmlStr + "

";

}

tooltip.html(htmlStr)

.style("left", (d3.event.pageX) + "px")

.style("top", (d3.event.pageY + 20) + "px")

.style("opacity", 0.75);

}

function addToolTipCir(d) {

var htmlStr;

if (d.name == "☿") {

htmlStr = "notes:解锁当前节点

";

}

if (d.name == "✂") {

htmlStr = "notes:裁剪当前节点与关系

";

}

if (d.name == "✠") {

htmlStr = "notes:拓展当前节点与关系

";

}

if (d.name == "◎") {

htmlStr = "notes:释放所有锁定的节点

";

}

if (d.name == "오") {

htmlStr = "notes:锁定所有节点

";

}

var tooltip = d3.select("body").append("div")

.attr("class", "tooltip") //用于css设置类样式

.attr("opacity", 0.0)

.attr("id", "tooltipCir");

tooltip.html(htmlStr)

.style("left", (d3.event.pageX) + "px")

.style("top", (d3.event.pageY + 20) + "px")

.style("opacity", 0.75);

}

```

```

// 生成圆弧需要的角度数据

var arcDataTemp = [{startAngle: 0, endAngle: 2 * Math.PI}];

var arc_temp = d3.svg.arc().outerRadius(26).innerRadius(20);

```

```

// 鼠标选中节点添加显示效果

var svg_selectNode;

function mouseSelect(d) {

svg_selectNode = svg.append("g")

.attr("id", "sel")

.attr("transform", "translate(" + d.x + "," + d.y + ")")

.selectAll("path.arc")

.data(arcDataTemp)

.enter()

.append("path")

.attr("fill", "#87CEFA")

.attr("d", function (d, i) {

return arc_temp(d, i);

});

}

```

```

// 全局停止力作用之间的影响

function stopForce() {

for (var i = 0; i < nodes.length; i++) {

var obj = nodes[i];

obj.fixed = true;

}

}

```

```

// 全局开始力作用之间的影响

function startForce() {

for (var i = 0; i < nodes.length; i++) {

var obj = nodes[i];

obj.fixed = false;

}

force.resume();

}

```

```

var nodesMark = [], edgesMark = [], indexNodeMark = []; // 缓存中所有已加载的数据标记

// 节点添加圆形分区(添加三页扇形)

function drawCirclePartition(d) {

// 圆形分区布局(数据转换)

var radius = 40;

var partition = d3.layout.partition()

.sort(null)

.size([2 * Math.PI, radius * radius]) // 第一个值域时2 PI,第二个值时圆半径的平方

.value(function (d) {

return 1;

});

// 绘制圆形分区图

// 如果以圆形的形式来转换数据那么d.x和d.y分别代表圆弧的绕圆心

// 方向的起始位置和由圆心向外的起始位置d.dx和d.dy分别代表各自的宽度

var arc = d3.svg.arc()

.startAngle(function (d) {

return d.x;

})

.endAngle(function (d) {

return d.x + d.dx;

})

.innerRadius(function (d) {

return 26;

})

.outerRadius(function (d) {

return 80;

});

var circlePart = partition.nodes(dataCirclePartition);

// "☿" 释放固定的节点

function releaseNode() {

d.fixed = false;

// force.start(); // 开启或恢复结点间的位置影响

force.resume();

}

// "✂" 删除当前节点以及当前节点到其它节点之间的关系

function removeNode() {

var newNodes = [];

for (var i = 0; i < nodes.length; i++) {

var obj = nodes[i];

if (obj.id != d.id) {

newNodes.push(obj);

}

}

var newedges = [];

for (var i = 0; i < edges.length; i++) {

var obj = edges[i];

if ((d.index != obj.source.index) && (d.index != obj.target.index)) {

newedges.push(obj);

}

}

nodes = newNodes;

edges = newedges;

var nIndex = function (d) {

return d.index;

};

var lIndex = function (d) {

return d.id;

};

// 通过添加'g'元素分组删除

svg.select("#circleAndText").selectAll("circle")

.data(nodes, nIndex)

.exit()

.remove();

svg.select("#circleAndText").selectAll("image")

.data(nodes, nIndex)

.exit()

.remove();

svg.select("#circleAndText").selectAll("text")

.data(nodes, nIndex)

.exit()

.remove();

svg.select("#lineAndText").selectAll("line")

.data(edges, lIndex)

.exit()

.remove();

svg.select("#lineAndText").selectAll("text")

.data(edges, lIndex)

.exit()

.remove();

}

```

```

// 扩展当前节点,距离为1

// 1.从rawData(rawNodes/rawEdges)中找出当前节点需要扩展的节点与关系数据

// 2.拿出需要扩展的数据到node/edges中去除已经绑定图形元素的数据

// 3.将过滤出的未绑定图形元素需要扩展的数据重新调用构图方法进行构图

// 添加从服务器实时加载数据的功能:基本思想与1~3类似

function extendNode() {

var index = d.index;

var arrEdges = [], arrIndex = [], arrNodes = [];

for (var i = 0; i < rawEdges.length; i++) {

if ((index == rawEdges[i].source.index) || (index == rawEdges[i].target.index)) {

arrEdges.push(rawEdges[i]);

if (index != rawEdges[i].source.index) {

arrIndex.push(rawEdges[i].source.index);

} else if (index != rawEdges[i].target.index) {

arrIndex.push(rawEdges[i].target.index);

}

}

edgesMark.push(rawEdges[i].id);

}

for (var i = 0; i < rawNodes.length; i++) {

for (var j = 0; j < arrIndex.length; j++) {

var obj = arrIndex[j];

if (rawNodes[i].index == obj) {

arrNodes.push(rawNodes[i]);

}

}

nodesMark.push(rawNodes[i].id);

indexNodeMark.push(rawNodes[i].index);

}

// nodes.push(arrNodes);

// edges.push(arrEdges);

var nodesRemoveIndex = [];

for (var i = 0; i < arrNodes.length; i++) {

var obj = arrNodes[i];

for (var j = 0; j < nodes.length; j++) {

var obj2 = nodes[j];

if (obj.index == obj2.index) {

nodesRemoveIndex.push(i);

}

}

}

var edgesRemoveIndex = [];

for (var i = 0; i < arrEdges.length; i++) {

var obj = arrEdges[i];

for (var j = 0; j < edges.length; j++) {

var obj2 = edges[j];

if (obj.id == obj2.id) {

edgesRemoveIndex.push(obj.id);

}

}

}

var coverNodes = [];

for (var i = 0; i < arrNodes.length; i++) {

var obj = arrNodes[i];

if (!isInArray(nodesRemoveIndex, i)) {

nodes.push(obj);

coverNodes.push(obj);

}

}

var coverEdges = [];

for (var i = 0; i < arrEdges.length; i++) {

var obj = arrEdges[i];

if (!isInArray(edgesRemoveIndex, obj.id)) {

edges.push(obj);

coverEdges.push(obj);

}

}

// console.log("找出需要扩展的数据");

// console.log(arrEdges);

// console.log(arrNodes);

// console.log("添加到原始需要绑定图形元素的数据集集合/与rawNodes,rawEdges服务器加载的原始数据保持区分");

// console.log(nodes);

// console.log(edges);

// 添加从服务器请求扩展数据

// var url = "http://222.216.195.154:7476/knowledge-graph/hello/dataSource/node/extend/" + d.id + "";

// d3.json(url, function (error, json) { // 服务器加载知识图谱数据

// if (error) {

// return console.warn(error);

// }

// console.log("从服务器请求的扩展数据:");

// var serverNodes = json.nodes;

// var serverEdges = json.links;

// console.log(serverNodes);

// console.log(serverEdges);

// console.log(nodesMark);

// console.log(edgesMark);

// // 重新设置INDEX

// var maxIndex = Math.max.apply(null, indexNodeMark);

// console.log("MAX:" + maxIndex);

//

// for (var i = 0; i < serverNodes.length; i++) {

// if (!isInArray(nodesMark, serverNodes[i].id)) {

// serverNodes[i].index = maxIndex + 1

// maxIndex = maxIndex + 1;

// nodes.concat(serverNodes[i]);

// console.log(serverNodes[i]);

// }

// }

// for (var i = 0; i < serverEdges.length; i++) {

// if (!isInArray(edgesMark, serverEdges[i].id)) {

// edges.concat(serverEdges);

// console.log(serverEdges[i]);

// }

// }

// console.log("服务器加载并且合并之后的数据:");

// console.log(nodes);

// console.log(edges);

// d3.select("#svgGraph").select("#svgOne").selectAll("*").remove(); // 清空SVG中的内容

// buildGraph();

// });

d3.select("#svgGraph").select("#svgOne").selectAll("*").remove(); // 清空SVG中的内容

buildGraph();

}

var arcs = svg.append("g")

.attr("id", "eee")

.attr("transform", "translate(" + d.x + "," + d.y + ")")

.selectAll("g")

.data(circlePart)

.enter()

.append("g")

.on("click", function (d) { // 圆形分区绑定Click事件

if (d.name == "☿") {

releaseNode();

}

if (d.name == "✂") {

removeNode();

}

if (d.name == "✠") {

extendNode();

}

if (d.name == "◎") {

startForce();

}

if (d.name == "오") {

stopForce();

}

d3.select("#eee").remove();

d3.select("#tooltipCir").remove();

});

arcs.append("path")

.attr("display", function (d) {

return d.depth ? null : "none"; // hide inner ring

})

.attr("d", arc)

.style("stroke", "#fff")

.style("fill", "#A9A9A9")

.on("mouseover", function (d) {

d3.select(this).style("fill", "#747680");

addToolTipCir(d); //添加提示框的div

})

.on("mouseout", function () {

d3.select("#tooltipCir").remove();

d3.select(this).transition()

.duration(200)

.style("fill", "#ccc")

var array = printPosition();

var distance = Math.sqrt(Math.pow((d.x - array[0]), 2) + Math.pow((d.y - array[1]), 2));

if (distance > 80) {

d3.select("#eee").remove(); // 删除节点扇形

}

});

arcs.append("text")

.style("font-size", "16px")

.style("font-family", "simsun")

.style("fill", "white")

.attr("text-anchor", "middle")

.attr("transform", function (d, i) {

// 平移和旋转

var r = 0;

if ((d.x + d.dx / 2) / Math.PI * 180 < 180) // 0-180度以内的

r = 180 * ((d.x + d.dx / 2 - Math.PI / 2) / Math.PI);

else // 180-360度

r = 180 * ((d.x + d.dx / 2 + Math.PI / 2) / Math.PI);

return "translate(" + arc.centroid(d) + ")" + "rotate(" + r + ")";

})

.text(function (d) {

return d.name;

});

return arcs;

}

```

```

// 添加描述关系文字

function add_text_edges() {

var svg_text_edges = svg.select("#lineAndText")

.selectAll("line.text")

.data(edges)

.enter()

.append("text")

.attr("id", function (d) {

return d.id;

})

.style("fill", "#ccc")

.attr("x", function (d) {

return (d.source.x + d.target.x) / 2

})

.attr("y", function (d) {

return (d.source.y + d.target.y) / 2

})

.text(function (d) {

return d.type;

})

.on("mouseover", function (d) { // 鼠标选中时触发

mouseSelectLine(d);

addToolTip(d); //添加提示框的div

})

.on("mouseout", function () {

d3.select("#relation").remove();

d3.select("#tooltip").remove();

})

.on("click", function () {

});

return svg_text_edges;

}

```

```

// 对于每一个时间间隔进行更新

function refresh() {

force.on("tick", function () { // 对于每一个时间间隔

// 更新连线坐标·

svg_edges.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;

});

// 更新节点以及文字坐标

svg_nodes.attr("transform", function (d) {

return "translate(" + d.x + "," + d.y + ")";

});

// 更新关系文字坐标

svg_text_edges.attr("x", function (d) {

return (d.source.x + d.target.x) / 2

})

.attr("y", function (d) {

return (d.source.y + d.target.y) / 2

});

});

}

```

```

var force, nodes = [], edges = [], rawNodes, rawEdges, mapNodes = new Map(); // 构建知识图谱需要操作的数据 (rawNodes, rawEdges将加载的原始构图数据缓存一份)

// 知识图谱可视化构建

function graph(data) {

// 先清空布局中的图形元素

// d3.select("#svgGraph").select("#svgOne").selectAll("*").remove();

// var serverD = data.nodes;

// var serverE = data.links;

// 去除NODES中重复的节点,如果有节点重复即将EDGES中的数据重新设置source值和target值

// serverD,serverE,nodes,edges

// var filterServerD = [];

// for (var i = 0; i < serverD.length; i++) {

// if (!isInArray(nodesIndexId, serverD[i].id)) {

// filterServerD.push(serverD[i]);

// }

// }

// 去重之后重新调整filterServerD的NODE index值

// mapNodes.forEach(function (value, key) {

// console.log(value);

// console.log(key);

// if (isInArray(nodesIndexId,key)){

//

// }

// });

// recordNodesIndex(serverD);

// console.log(nodesIndexValue);

// 多数组连接

// nodes = nodes.concat(data.nodes);

// edges = edges.concat(data.links);

// console.log(nodes);

// console.log(edges);

// rawNodes = nodes;

// rawEdges = edges;

// // 定义力布局(数据转换)

// force = d3.layout.force()

// .nodes(nodes) // 指定节点数组

// .links(edges) // 指定连线数组

// .size([width, height]) // 指定范围

// .linkDistance(150) // 指定连线长度

// // .gravity(0.02) // 设置引力避免跃出布局

// .friction(0.9) // 设置摩擦力速度衰减

// .charge(-400); // 相互之间的作用力

// force.start(); // 开始作用

// buildGraph();

}

```

```

var svg_edges, svg_nodes, svg_text_edges; // 需要动态更新的函数(dynamic update function)

// Strat build Knowledge Graph/Vault

function buildGraph() {

console.log("开始构建可视化知识图谱:");

console.log(nodes);

console.log(edges);

svg_edges = add_edges(); // 添加连线与箭头

svg_nodes = add_nodes(); // 添加节点与文字

svg_text_edges = add_text_edges(); // 添加描述关系的文字

refresh(); // 对于每一个时间间隔进行更新

force.resume(); // 必须添加否则图形元素更新不及时

}

```

```

// 服务器加载数据

var dataCirclePartition;

function load() {

d3.json("http://222.216.195.154:7476/knowledge-graph/hello/dataSource/type/1", function (error, root) { // 服务器加载节点圆形分区数据

if (error) {

return console.warn(error);

}

dataCirclePartition = root;

});

d3.json("http://222.216.195.154:7476/knowledge-graph/hello/dataSource/type/2", function (error, json) { // 服务器加载知识图谱数据

if (error) {

return console.warn(error);

}

console.log("初始加载:");

console.log(json.nodes);

console.log(json.links);

graph(json);

});

// d3.json("http://222.216.195.154:7476/knowledge-graph/hello/dataSource/node/extend/99817", function (error, json) { // 服务器加载知识图谱数据

// if (error) {

// return console.warn(error);

// }

// console.log("初始加载:");

// console.log(json);

// graph(json);

// });

}

// 初始化图数据库配置信息

startNeo4j();

// 执行知识图谱数据可视化

load();

// 传入NODE ID与NODE INDEX,节点的INDEX与构图时数据加载的顺序密切相关

function loadById(id, maxNodeIndex, nodesIdList) {

// var para = ["id:" + id, "maxNodeIndex:" + maxNodeIndex, "nodesIdList:" + nodesIdList];

var para = {"id": id, "maxNodeIndex": maxNodeIndex, "nodesIdList": nodesIdList};

console.log(para);

d3.json("http://222.216.195.154:7476/knowledge-graph/hello/dataSource/node/idIndex/" + para, function (error, data) { // 服务器加载知识图谱数据

if (error) {

return console.warn(error);

}

console.log("动态ID加载的数据:");

console.log(nodesMark);

console.log(edgesMark);

console.log(nodes);

console.log(edges);

console.log(data);

graph(data);

});

}

function loadZdrSearch(json) {

d3.json("http://222.216.195.154:7476/knowledge-graph/hello/dataSource/type/1", function (error, root) { // 服务器加载节点圆形分区数据

if (error) {

return console.warn(error);

}

dataCirclePartition = root;

});

graph(json);

}

// 执行知识图谱数据可视化

// loadById(id);

```

启动入口类KnowledgeGraphApplication之后,

调用接口:http://localhost:7476/knowledge-graph/hello/index

此接口调用控制类加载index.html,HTML中调用了js文件加载展示数据,详细的实现过程请看完整的代码注释。

>代码目录结构说明一:

![代码目录结构说明](/contentImages/image/20180708/1NODaHkjOQEv1cSUoil.png)

>代码目录结构说明二:

![代码目录结构说明](/contentImages/image/20180708/URaahjGrTTzIC2iqcxV.png)

#### 四、可视化效果(所有可视化效果均带有力布局效果)

######1.节点与关系均带有选中效果,节点关系裁剪与扩展

☿解锁当前节点

✂ 剪切当前节点于关系

✠ 扩展当前节点与关系

오 固定所有节点

◎ 解锁所有节点

>实体扩展功能:

![实体扩展功能](/contentImages/image/20180708/8dvzXzSMkz65KW1OFsd.png)

>节点效果:

![节点效果](/contentImages/image/20180708/o8Xhzc2DYLoNXfIzbMY.png)

######2.完整示例

>完整效果显示示例一:

![完整示例](/contentImages/image/20180708/WowrmiblqPuogs6Wwgt.png)

>完整效果显示示例二:

![](/contentImages/image/20180708/oosOoMBoeFcRGIKem79.png)

python知识图谱可视化_知识图谱可视化相关推荐

  1. python知识图谱实战_知识图谱实战

    原标题:知识图谱实战 知识图谱是近来非常红火的技术,融合网络爬虫,自然语言处理,机器学习,深度学习,图数据库,复杂网络分析等多种热门技术于一身,技术含量密集,在构造语义搜索,问答平台,高智能的人机界面 ...

  2. python 知识图谱数据库_知识图谱和 Neo4j 浅析-数据库

    编辑推荐: 本文来自于51cto,介绍了什么是知识图谱,知识图谱的应用场景,知识图谱的构建,知识图谱的存储以及 neo4j 的性能测试,neo4j图数据库优化等知识. 在当前大数据行业中, 随着算法的 ...

  3. pytorch卷积可视化_使用Pytorch可视化卷积神经网络

    pytorch卷积可视化 Filter and Feature map Image by the author 筛选和特征图作者提供的图像 When dealing with image's and ...

  4. python文献知识图谱可视化_知识图谱可视化工具(知识图谱可视化python)

    知识图谱可视化工具免费杭州市西湖区教育装备保障服务中心 除了知识图,图还能做什么?编者注:作者的高级解决方案顾问包汉林.本文将集中在三个方面,侧重于图数据库和图分析的价值,并列举图分析应用程序的一些方 ...

  5. python 知识图谱 推理_知识图谱推理与实践 (2) -- 基于jena实现规则推理

    本章,介绍 基于jena的规则引擎实现推理,并通过两个例子介绍如何coding实现. 规则引擎概述 jena包含了一个通用的规则推理机,可以在RDFS和OWL推理机使用,也可以单独使用. 推理机支持在 ...

  6. python知识点智能问答_基于知识图谱的智能问答机器人

    研究背景及意义 智能问答是计算机与人类以自然语言的形式进行交流的一种方式,是人工智能研究的一个分支. 知识图谱本质上是一种语义网络,其结点代表实体(entity)或者概念(concept),边代表实体 ...

  7. python交互式绘图库_一个交互式可视化Python库——Bokeh

    本篇为<Python数据可视化实战>第十篇文章,我们一起学习一个交互式可视化Python库--Bokeh. Bokeh基础 Bokeh是一个专门针对Web浏览器的呈现功能的交互式可视化Py ...

  8. python动态排名可视化_动态排名可视化 | 带你领略编程语言20年风云变化

    原标题:动态排名可视化 | 带你领略编程语言20年风云变化 作者 | 周萝卜 来源 | 萝卜大杂烩 2019已经过去,回看编程语言20年真是风云变化! 从 TIOBE 榜(热门榜)上来看,Java.C ...

  9. python声音可视化_声音的可视化处理

    声音的可视化处理 下一步需要做声音信号的处理,今天就把声音的可视化的程序代码做一下. 主要完成声音的波形显示(时域信号)和声音的频谱显示(频域信号) 虽然涉及傅里叶变换等复杂的处理,采用matplot ...

最新文章

  1. Scala分支控制 if-else之单分支的使用
  2. Linux按照CPU、内存、磁盘IO、网络性能监测
  3. 洛谷团队月赛题:题解
  4. mysql数据库设计中的14个技巧
  5. linux服务器,ping没问题,http请求经常超时、时好时坏的解决办法
  6. pythonの连接MySQL数据库
  7. java.lang.IllegalArgumentException: An invalid character [10] was present in the Cookie value
  8. hive 的功能和架构
  9. 现代控制理论-6李雅普诺夫稳定性
  10. java 同步和异步_Java中的同步与异步详细介绍
  11. 信号与系统实验一:基本信号的产生和实现
  12. 第四章 向量代数与空间解析几何
  13. 很多人在睡觉的时候半梦半醒时,感…
  14. 1.1微信支付之现金红包 - Java 开发
  15. Camera 之水波纹和banding现象
  16. android验证数字字母和特殊字符,正则表达式必须包含字母数字和特殊字符
  17. ttbf 慢 php,連接數據庫不同方式會影響TTBF快慢
  18. 蛋白质相互作用系列:GN快速算法
  19. 微机原理知识点总结10-12
  20. 车票购买最低消费问题java_浅析12306售票算法(java版)

热门文章

  1. python中字符串转xml对象_Python实现对象转换为xml的方法示例
  2. 【51单片机快速入门指南】2.4:74HC595、LED点阵屏及其SPI控制
  3. Android开发之Handler
  4. 奔跑吧Linux内核初识
  5. [react] React怎样引入svg的文件?
  6. 前端学习(3347):数组方法的运用和总结稀疏数组
  7. [vue] 你有使用过JSX吗?说说你对JSX的理解
  8. [css] 写出主流浏览器内核私有属性的css前缀
  9. [css] 移动页面底部工具条有3个图标,如何平分?在设置边框后最后一个图标掉下去了怎么办?
  10. 工作312:uni-弹出框显示数据