ネットワークグラフを描画する際に、しきい値を指定して一部のノード/エッジを不可視化したいのです
javascript/vis.js をつかってネットワークグラフを書き始めました。現在、以下に上げました
・index.html
・style.css
・script.js
を用いて、グラフの描画そのものはできています。自分の環境では、これら3つのファイルを一つのディレクトリに配置し、index.html をダブルクリックすると描画は正常になされます(macOS バージョン: 10.15.7 Catalina/Google Chrome バージョン: 98.0.4758.102(Official Build) (x86_64))。肝心なコードは script.js にありますが、これはNomuraS様がCodePenのページ( https://codepen.io/NomuraS )上で公開してくださっているサンプルコード vis.js example1, vis.js example2 を組み合わせることでほぼ仕上がっています。
解決したいこと
script.js に示しました通り、各ノードに weight という値を振り分けています。その上で、しきい値を指定し、その値未満のweightをもつノードとそれにつながっているエッジを不可視化(たとえば表示を透明にする等)したいのですが、その方法を調べきれず手を束ねています。まず、この描画されたwebページの上でしきい値を入力するためのインターフェースを用意できないでいます(このために各種のバーがインターフェースに備えられているサンプルを探したのですが)。そして、ノードとエッジを不可視化することに成功していません。
しきい値に対してはボックスに数字を入力する、あるいはバーでコントロールするなど、動的な方法を取りたいのです。
* なお、ノードカラーとエッジカラーを別々に指定できないのでしょうか。
edges: {
arrows: 'to', // エッジに矢印を付けて有向グラフにする
smooth: true // falseにするとエッジが直線になる
},
→描画ok
edges: {
arrows: 'to', // エッジに矢印を付けて有向グラフにする
smooth: true // falseにするとエッジが直線になる
color: "skyblue" // エッジカラー
},
→どうも許されていない書き方。グラフが表示されず。
* これはまだ十分時間をかけて調べていないままの質問で恐縮しますが、各ノードの描画画面上での座標に関して、次の2件につきましてもよければご教示ください。
1 力学モデル(物理シミュレーションモデル)で配置された各ノードの座標を得る仕組み
2 各ノードの座標の初期値を指定する仕組み
index.html
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - vis.js example2 by NomuraS</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<html>
<head>
<meta charset="utf-8" />
<title>Network | Manipulation</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis-network.min.css" rel="stylesheet" type="text/css" />
</head>
<body onload="draw();">
<div id="network-popUp">
<span id="operation">node</span>
<br>
<table style="margin:auto;">
<tr>
<td>id</td>
<td>
<input id="node-id" value="new value" />
</td>
</tr>
<tr>
<td>label</td>
<td>
<input id="node-label" value="new value" />
</td>
</tr>
</table>
<input type="button" value="save" id="saveButton" />
<input type="button" value="cancel" id="cancelButton" />
</div>
<br />
<div id="mynetwork"></div>
<div id="config"></div>
</body>
</html>
<!-- partial -->
<script src="./script.js"></script>
</body>
</html>
style.css
#mynetwork {
position: relative;
width: 800px;
height: 600px;
border: 1px solid lightgray;
}
#network-popUp {
display: none;
position: absolute;
top: 350px;
left: 170px;
z-index: 299;
width: 250px;
height: 120px;
background-color: #f9f9f9;
border-style: solid;
border-width: 3px;
border-color: #5394ed;
padding: 10px;
text-align: center;
}
#config {
float: left;
width: 400px;
height: 600px;
}
script.js
var network = null;
var nodes = new vis.DataSet([
{ id: 1, label: '環境', weight: 100 },
{ id: 2, label: 'エネルギー', weight: 86 },
{ id: 3, label: '省エネ', weight: 40 },
{ id: 4, label: 'ESD', weight: 34 },
{ id: 5, label: 'HEM', weight: 13 },
{ id: 6, label: '家庭', weight: 89 },
{ id: 7, label: '生き物', weight: 75 },
{ id: 8, label: '植物', weight: 70 },
{ id: 9, label: '地域', weight: 55 },
{ id: 10, label: '動物', weight: 68 },
{ id: 11, label: '学校', weight: 45 },
{ id: 12, label: '社会', weight: 66 }
]);
var edges = new vis.DataSet([
{ from: 1, to: 2},
{ from: 1, to: 7},
{ from: 1, to: 8},
{ from: 2, to: 1},
{ from: 2, to: 3},
{ from: 3, to: 4},
{ from: 3, to: 5},
{ from: 3, to: 6},
{ from: 4, to: 1},
{ from: 4, to: 5},
{ from: 5, to: 6},
{ from: 6, to: 3},
{ from: 7, to: 1},
{ from: 7, to: 8},
{ from: 7, to: 10},
{ from: 9, to: 4},
{ from: 9, to: 6},
{ from: 9, to: 11},
{ from: 9, to: 12}
]);
// create a network
var data = {
nodes: nodes,
edges: edges
};
function destroy() {
if (network !== null) {
network.destroy();
network = null;
}
}
function draw() {
destroy();
nodes = [];
edges = [];
// create a network
var container = document.getElementById('mynetwork');
var options = {
physics: false, // 物理シミュレーションをオフにする
nodes: {
shape: 'box', // ノードの形をellipseからboxに
size: 20, // ノードの大きさ
font: {
boldital: { color: 'pink' }, // <i><b>aaa</b></i>タグのカラー
ital: { color: 'orange' }, // <i>aaa</i>タグのカラー
mono: { color: 'blue' }, // <code>aaa</code>タグのカラー
bold: { color: 'purple' }, // <b>aaa</b>タグのカラー
// color: 'yellow', // タグなしのノードの文字の色
color: 'black', // タグなしのノードの文字の色
},
color: "skyblue" // ノードカラー
},
edges: {
arrows: 'to', // エッジに矢印を付けて有向グラフにする
smooth: true // falseにするとエッジが直線になる
},
manipulation: {
addNode: function (data, callback) {
// filling in the popup DOM elements
document.getElementById('operation').innerHTML = "Add Node";
document.getElementById('node-id').value = data.id;
document.getElementById('node-label').value = data.label;
document.getElementById('saveButton').onclick = saveData.bind(this, data, callback);
document.getElementById('cancelButton').onclick = clearPopUp.bind();
document.getElementById('network-popUp').style.display = 'block';
},
editNode: function (data, callback) {
// filling in the popup DOM elements
document.getElementById('operation').innerHTML = "Edit Node";
document.getElementById('node-id').value = data.id;
document.getElementById('node-label').value = data.label;
document.getElementById('saveButton').onclick = saveData.bind(this, data, callback);
document.getElementById('cancelButton').onclick = cancelEdit.bind(this, callback);
document.getElementById('network-popUp').style.display = 'block';
},
addEdge: function (data, callback) {
if (data.from == data.to) {
var r = confirm("Do you want to connect the node to itself?");
if (r == true) {
callback(data);
}
} else {
callback(data);
}
}
},
configure: {
filter: function (option, path) {
if (path.indexOf('physics') !== -1) {
return true;
}
if (path.indexOf('smooth') !== -1 || option === 'smooth') {
return true;
}
return false;
},
container: document.getElementById('config')
}
};
network = new vis.Network(container, data, options);
}
function clearPopUp() {
document.getElementById('saveButton').onclick = null;
document.getElementById('cancelButton').onclick = null;
document.getElementById('network-popUp').style.display = 'none';
}
function cancelEdit(callback) {
clearPopUp();
callback(null);
}
function saveData(data, callback) {
data.id = document.getElementById('node-id').value;
data.label = document.getElementById('node-label').value;
clearPopUp();
callback(data);
}