Tangle分析工具
===
# tool 目的
## 有 coordinator
### 觀察 milestone
從 milestone 在 Tnagle 上的位置去了解那些交易不會指向 , 哪些交易 milestone會驗證
## 沒有 coordinator
### 交易的確認
觀察在 Tangle 的一筆交易 , tip 驗證的比例隨時間的變化以及增加1%確認度的機率
### 衝突交易及相關 bundle
觀察有衝突交易的情況 , 新issue的交易如何指向 tip
### 交易的累積權重
觀察在 Tangle 的一筆交易 , 累積權重隨時間的變化
### random walk 選到 tip 的機率
從顯示選到 tip 的機率可以觀察 tip selection 對 Tangle 的影響
# 預計功能
## 操作
### 主畫面

### Node management
### node Tangle analysis

#### node information
##### subtangle
* live
從 $getTips$ 所得到的 tip , 畫出接下來 issue 的交易(新 tips)
* 可以從驗證的方向或被驗證的方向畫出DAG
* 可以在Tangle標示交易的狀態
交易狀態的示意圖:
```graphviz
digraph init{
rankdir=RL;
a[ label="c" color=yellow, fontcolor=yellow, fontsize=24, shape=box style = filled];
b[label="C1" color=black, fontcolor=red, fontsize=24, shape=box ];
c[label="C1" color=green, fontcolor=red, fontsize=24, shape=box style = filled]
e[label="e" color=green, fontcolor=green, fontsize=24, shape=box style = filled]
d[label="B3" color=black, fontcolor=blue, fontsize=24, shape=box]
21[label="" color=black, fontcolor=blue, fontsize=24, shape=box]
11[label="" color=yellow, fontcolor=yellow, fontsize=24, shape=box style = filled]
31[label="B2" color=black, fontcolor=blue, fontsize=24, shape=box]
22[label="" color=black, fontcolor=blue, fontsize=24, shape=box]
12[label="" color=black, fontcolor=blue, fontsize=24, shape=box]
32[label="" color=black, fontcolor=blue, fontsize=24, shape=box]
41[label="" color=black, fontcolor=blue, fontsize=24, shape=box]
23[label="" color=gray, fontcolor=black, fontsize=24, shape=box style = filled]
13[label="" color=gray, fontcolor=blue, fontsize=24, shape=box style = filled]
42[label="B1" color=black, fontcolor=blue, fontsize=24, shape=box]
33[label="" color=gray, fontcolor=blue, fontsize=24, shape=box style = filled]
a -> c;
b -> c;
a -> c;
b -> c;
e -> a;
e -> a;
d -> a;
d -> b;
21->e;
21->d;
11->e;
11->e;
31->d;
31->d;
22->21;
22->31;
41->e;
41->d;
12->11;
12->21;
32->21;
32->31;
23->22;
23->32;
42->41;
42->31;
13->12;
13->22;
33->22;
33->42;
}
```
1. 黃色的長方形就是 milestone
2. 綠色的長方形是確認的交易
3. $\color{red}{C1}$ 代表第1組的衝突交易
4. $\color{blue}{B1}$ , $\color{blue}{B2}$ , $\color{blue}{B3}$ 代表同個 bundle , 不同的 bundle index
5. 灰色的長方形代表 tip
* 是否需要其他的交易狀態?(ex:無效的bundle)
#### 折線圖
* 交易隨著時間被驗證的 tip 比例
X-軸是時間或查詢次數
Y-軸是該交易被多少 tip 驗證的比例
* 交易的累積權重隨著時間的變化
X-軸是時間或查詢次數
Y-軸是該交易的累積權重
#### 統計
* random walk
在 subtangle 顯示 random walk 走到各交易的機率
* tip selection
在 subtangle 顯示每個 tip 被驗證的機率(一次 tip selection)
* 交易被 tips 指向的比例
在 suntangle 顯示每個交易被多少比例的 tip 指向
## 顯示 subtangle
* 可以縮放 , 拖曳的 svg
用 svg 畫 subtangle
### 一些問題
1. 交易太多拖曳與縮放會變慢
2. 交易被其他交易遮擋
## 額外功能
* subtangle 輸出圖檔
* 折線圖輸出圖檔
* subtangle 增長的動畫
* 選擇不同 net 的 node (server) , 可以同時觀察不同 net 上的 Tangle
## 要保留的 code
### 參考的commits
* master
[Highlighting approving nodes](https://github.com/DLTcollab/tangle-analytics/commit/cc5b913a094618d6d9495d030096d9b753add8cb)
getAncestors() , getApprovingNodes() 保留
[Improved arrowhead behavior](https://github.com/DLTcollab/tangle-analytics/commit/c71bc84a5de0321ec8b602ac63ab244a101a3c38)
generateLinkPath() 保留
[Added outline to hovered node](https://github.com/DLTcollab/tangle-analytics/commit/a89466ec71cc8d1acebb08acd861ec14a08ae73d)
Node() 保留與選取特效
[Fixed right margin issue](https://github.com/DLTcollab/tangle-analytics/commit/3da77ddf96336779afc60cc64559171ae74f75fd)
xFromTime() 函數會去掉
[Added weighted MCMC algorithm](https://github.com/DLTcollab/tangle-analytics/commit/ce419d575de580ca78501d6cf6e106e879f3a81c)
test file 會去掉 , 剩下的算法保留
[Highlight descendents on mouse hover, added tests](https://github.com/DLTcollab/tangle-analytics/commit/5414649a18105d7b4045c49310b284fac0ff1be5)
mouseEntersNodeHandler() 與 mouseLeavesNodeHandler() 會保留與改名
[Show tips in gray](https://github.com/DLTcollab/tangle-analytics/commit/e3ca87fe09a07feba16563e108d0b2ba1b1b61a9)
getTips() 保留
[Window resize support](https://github.com/DLTcollab/tangle-analytics/commit/248d3fcdea9d2a92973a7d862406f872e081a486)
會去掉window的限制
[Links to approved nodes turn red](https://github.com/DLTcollab/tangle-analytics/commit/d7d334d372eeb4be31b0af6a59880377ae27108b)
保留被指向的交易是紅色的功能
[Tooltip over slider to show value](https://github.com/DLTcollab/tangle-analytics/commit/1db2fa1d16f434ed43299791bcc9443f8e77d972)
觀望 , 有些統計的功能可能需要用到
[Rescale x coordinates to cover window and stay in it](https://github.com/DLTcollab/tangle-analytics/commit/6259498c4d2f88e2c39f9631517545f87ef2b62b)
會去掉在window內的限制
* one-by-one
[Confirmation confidence calculation](https://github.com/DLTcollab/tangle-analytics/commit/a593e26d9f3ae5d5fad1b3d4d1b78055d2c37c31)
觀望
# 資料來源
## 用 findTransactions 拿取
## 從 rocksDB 讀取
# 修改過程
[source code](https://github.com/KevinKu/iotavisualization/tree/remove_unnecessary_code)
### 模擬 Tangle 的圖
畫 Tangle 主要是這個[函數](https://github.com/KevinKu/iotavisualization/blob/master/src/components/Tangle.js#L116)
[Node](https://github.com/KevinKu/iotavisualization/blob/master/src/components/Tangle.js#L78) 是 Tangle 中的交易
而在 [TangleContainer.js](https://github.com/KevinKu/iotavisualization/blob/master/src/containers/TangleContainer.js#L343)
中的code:
```javascript=
<Tangle links={this.state.links}
nodes={this.state.nodes}
nodeCount={6}
width={width}
height={height}
leftMargin={leftMargin}
rightMargin={rightMargin}
nodeRadius={this.state.nodeRadius}
mouseEntersNodeHandler={this.mouseEntersNodeHandler.bind(this)}
mouseLeavesNodeHandler={this.mouseLeavesNodeHandler.bind(this)}
approvedNodes={approved.nodes}
approvedLinks={approved.links}
approvingNodes={approving.nodes}
approvingLinks={approving.links}
hoveredNode={this.state.hoveredNode}
tips={getTips({
nodes: this.state.nodes,
links: this.state.links,
})}
showLabels={this.state.nodeRadius > showLabelsMinimumRadius ? true : false}
/>
```
可以看到
```javascript=
links={this.state.links}
nodes={this.state.nodes}
```
都是使用[TangleContainer](https://github.com/KevinKu/iotavisualization/blob/master/src/containers/TangleContainer.js#L114)的狀態(state)
所以只要在這元件下用setState()去修改nodes和links就可以畫出不同的Tangle
### 畫圖參數的格式
在[generateData.js](https://github.com/KevinKu/iotavisualization/blob/master/src/shared/generateData.js)可以找到相關的格式
nodes:
```javascript=
{
name: `${nodes.length}`,
time,
x: 300,
y: 200,
}
```
links:
```javascript=
const links = [];
links.push({source: node, target: tips[0]});
```
[GenerateSubTangle](https://github.com/KevinKu/iotavisualization/blob/remove_unnecessary_code/src/shared/generateData.js#L4)改寫:
```javascript=
let nodes = [];
nodes.push({name:'0',time:'0',});
nodes.push({name:'1',time:'0.5',});
nodes.push({name:'2',time:'1',});
nodes.push({name:'3',time:'1.5',});
nodes.push({name:'4',time:'2',});
const links = [];
links.push({source: nodes[1], target: nodes[0]});
links.push({source: nodes[2], target: nodes[0]});
links.push({source: nodes[2], target: nodes[1]});
links.push({source: nodes[3], target: nodes[2]});
links.push({source: nodes[3], target: nodes[1]});
links.push({source: nodes[4], target: nodes[3]});
links.push({source: nodes[4], target: nodes[2]});
return {
nodes,
links,
};
```
這樣就能畫出這樣的圖:

### 點button新增交易
為了 $live$ 顯示新加入 $SubTangle$ 的 $tip$ 所做的修改
結果圖:


code:
```javascript=
let tangle = "";
let c_nodes = this.state.nodes;
let c_links = this.state.links;
let c_count = this.state.count + 1;
if(this.state.count == 0){
tangle = GenerateSubTangle({RootTransactionHash});
}else if(this.state.count == 1){
c_nodes.push({name:c_count.toString(),time:c_count.toString(),});
c_links.push({source: c_nodes[2], target: c_nodes[0]});
c_links.push({source: c_nodes[2], target: c_nodes[1]});
tangle = {nodes:c_nodes,links:c_links};
}else{
c_nodes.push({name:c_count.toString(),time:c_count.toString(),});
c_links.push({source: c_nodes[c_count], target: c_nodes[c_count - 2]});
c_links.push({source: c_nodes[c_count], target: c_nodes[c_count - 1]});
tangle = {nodes:c_nodes,links:c_links};
}
................................................................
this.setState({
nodes: tangle.nodes,
links: tangle.links,
nodeRadius,
count: c_count,
}, ... )
```
### Await無法使用
由[issue](https://github.com/iotaledger/iota.lib.js/issues/168)知道await之類不能使用
嘗試[curl-request](https://www.npmjs.com/package/curl-request)來跟node拿取資料
同事找到的可使用then的[library](https://github.com/jimthedev/iotap)
用以上的library可以使用

```javascript=
const server_node = new IOTA({
'host':'https://potato.iotasalad.org' ,
'port':14265
});
const s_node = iotap.create(server_node);
const approve_list = s_node.findTransactions({'approvees': ["9DCRWEHKAPXZJTISHACOVKLPLLVBHBHPKZUPSHZOEZTQQGXEBGXIVGFSSZYHBIGRPQZCVVSRYYMUZ9999"]});
Promise.all([approve_list]).then(([approve_list])=>{console.log(approve_list)});
```
# SubTangle的算法
由於還有 paint milestone 與 paint confirmed transaction 的需求
以及 live 的選項
考慮以 setInterval 間隔1秒畫一次 approvees 的結果
預計node的格式
改成下列
```json=
{name:"",time:"",transactionHash:"",nodeIndex:"",}
```
先實做只查詢一層

上圖是milestone的

code:
```javascript=
GraphSubTangle() {
const nodeRadius = getNodeRadius(6);
let c_subTangleTips = [];
let c_nodes = [];
c_nodes.push({name:'0',time:0,transactionHash:this.state.rootTransactionHash,nodeIndex:0,});
c_subTangleTips.push({name:'0',time:0,transactionHash:this.state.rootTransactionHash,nodeIndex:0,});
let ID = setInterval(()=>{this.DrawNextApprovees();},3000);
this.setState({
nodes: c_nodes,
links: [],
subTangleTips: c_subTangleTips,
time: 0,
nodeRadius,
intervalID: ID,
live: 1,
}, );
}
DrawNextApprovees(){
const nodeRadius = getNodeRadius(6);
let tangle = "";
let c_subTangleTips = [];
let c_nodes = this.state.nodes;
let c_links = this.state.links;
let c_time = this.state.time + 0.2;
let s_node = this.state.requestServer;
if(this.state.live == 0){
return ;
}
if(this.state.subTangleTips.length > 0){
for(let findTransaction of this.state.subTangleTips){
const approve_list = s_node.findTransactions({'approvees': [findTransaction.transactionHash]});
Promise.all([approve_list]).then(([approve_list])=>{
if(approve_list.length > 0){
for(let a_transaction of approve_list){
let exist = 0;
for(let site of c_nodes){
if(a_transaction == site.transactionHash){
exist = 1;
}
}
if(exist == 0){
let c_nodeIndex = c_nodes.length;
c_nodes.push({name:c_nodeIndex.toString(),time:c_time,transactionHash:a_transaction,nodeIndex:c_nodeIndex,});
c_subTangleTips.push({name:c_nodeIndex.toString(),time:c_time,transactionHash:a_transaction,nodeIndex:c_nodeIndex,});
c_links.push({source:c_nodes[c_nodeIndex],target:c_nodes[findTransaction.nodeIndex]});
}
}
}
});
}
}
tangle = {nodes:c_nodes,links:c_links};
console.log(c_subTangleTips);
const {width, height} = this.state;
for (let node of tangle.nodes) {
node.y = height/4 + Math.random()*(height/2),
node.x = width/2; // required to avoid annoying errors
}
this.force.stop();
this.setState({
nodes: tangle.nodes,
links: tangle.links,
subTangleTips: c_subTangleTips,
time: c_time,
nodeRadius,
}, () => {
// Set all nodes' x by time value after state has been set
this.recalculateFixedPositions();
});
this.force.restart().alpha(1);
return ;
}
```
接下來往拖曳跟縮放SVG圖來處理
### 拖曳跟縮放SVG圖
使用這個[套件](https://github.com/chrvadala/react-svg-pan-zoom)
目前做出來的效果:

接下來想去掉d3 , 改成決定每筆交易在svg的位置

回覆了指向與被指向的標示
預計加入三類Components
[span]()
[Text Fields](https://material-ui.com/demos/text-fields/)
[Switches with FormGroup](https://material-ui.com/demos/selection-controls/#switches-with-formgroup)
三類分別對應
$\color{blue}{span}$ :

$\color{blue}{Text \space Fields}$ :
搜尋在 Tangle 內的交易

管理與繪製 Tangle

$\color{blue}{Switches with FormGroup}$ :

# 11/15
[TangleManagement.js](https://github.com/DLTcollab/tangle-analytics/blob/master/src/components/TangleManagement.js) 可以在瀏覽器顯示

寫了 [TangleManagementContainer.js](https://github.com/DLTcollab/tangle-analytics/blob/master/src/containers/TangleManagementContainer.js)並可以在瀏覽器上顯示

接下來要把 Graph , STOP , CARRY ON 功能補完
# 11/16

交易 Hash 可以輸入字串
目前 nodes 與 links 無法正確顯示 DAG 的結構
不過逐漸把 TangleContainer 的功能拆解
另外 , IOTA node 的 object
需要另一個 Container 來處理
找到的[svg 縮放 tool](https://github.com/ganxunzou/react-resize-svg) , 等拆解完後來測測看
# 12/8
來重構 $GraphTangle$
與 $GetNextApprovees$ 兩個函數
先講原本的實作有什麼問題
## 某些DAG的結構不對
這算是原本算法的 bug
以一個 Tangle 為例子:
```graphviz
digraph init{
rankdir=RL;
a[ label="a" color=blue, fontcolor=blue, fontsize=24, shape=box];
c[label="c" color=blue, fontcolor=blue, fontsize=24, shape=box]
d[label="d" color=blue, fontcolor=blue, fontsize=24, shape=box]
e[label="e" color=blue, fontcolor=blue, fontsize=24, shape=box]
c -> a;
c -> a;
d -> a;
d -> a;
e->d;
e->c;
}
```
當 Tangle 是上圖時 , $d$ 與 $e$ 的連線會沒有紀錄到
因為查詢 $c$ 的時候 , $e$ 會被加到 nodes
接下來來查詢 $d$ 的時候 , 由於 $e$ 已經在 nodes 了
所以就換下一個直接驗證的交易 , 這樣 $d$ 與 $e$ 的連線就沒有加到 links
所以圖畫出來就不對了
## 無法補畫 lazy tip
整個畫圖的邏輯 , 是從 subTangle 的 tips 找出直接驗證 tips 的交易畫出來的
這會使 lazy tip 不會被查詢到
所以 lazy tip 不會被畫出來
# 1/4
先補輸入 node url 與 port 的欄位
因為 new IOTA() 的建構函數需要
結果:

# 1/10
測試之前輸入 node 的 UI
並寫了一個測試用的按鈕

接下來要重寫 GetNextApprovees 與 GraphTangle
# 1/11
由於要重寫渲染 Tangle 的函數
需要重新定義 node(交易) 的格式
然後刪除了一個變數(subTangleTip)
讓 TangleManagementContainer 單純查詢 Tangle
幾個關於格式的問題
1. 每個 node 要不要有高度?
# 1/15
關於 node 要不要有高度
我想是要的 , 因為在畫 Tangle 的時候 , 應該會重用 IF 模擬的函數
函數會使用到 time 這個參數 , 預計用高度把 time 取代掉
由於 IF 模擬的函數有使用 d3 的 force layout , 可以避免兩筆交易重疊的情況
目前 node(交易) 的格式定成這樣:
```javascript=
{name:"",height:0,nodeIndex:0,}
```
解釋每個欄位的意思
* name : 存放交易 hash , 這欄位就之前測試結果 , 是必須的
* height : 高度 , 從 TangleRoot 開始算起 , 定義白皮書有提到
* nodeIndex : 建構 links 時使用 , 意義是某個交易 hash 在 nodes 的 index
然後測試的時候發現了 clear 這個功能沒寫好 , 順便 fix 了
[fix clear and rewrite GraphTangle](https://github.com/DLTcollab/tangle-analytics/commit/85450278072d30d0643343b2f3b898a618f34e27)
# 1/17 and 1/18
寫一下要處理的四種狀況
講一下前提
用某個交易 hash , 去跟 node 查詢直接驗證的交易
會得到一組交易 hash 的列表
這邊討論的是這直接驗證交易的交易列表 , 取出其中一筆交易
與查詢傳入的交易之間的關係
會有四種情況 , 以下討論
## nodes 沒有 , links 沒有
:::info
標準的新交易的情況
所以要加入到nodes
要加入驗證關係到links
然後高度直接計算
就是被驗證的交易高度+1
:::
## nodes 有 , links 沒有
:::info
這代表links紀錄到trunk或branch
但還有缺少的直接驗證關係
所以要補links
然後要檢查高度要不要做更新
每筆交易高度的算法都是取trunk或branch最高的加一
:::
## nodes 有 , links 有
:::info
代表目前交易與被直接驗證交易的組合沒有變化
所以什麼都不做 , 直接跳過
:::
## nodes 沒有 , links 有
:::info
這種是不可能的 , 不考慮
:::
# 1/23
更新完成
[Finish create nodes and links function](https://github.com/DLTcollab/tangle-analytics/commit/22774909f8f7318eb038b7cc89235abac5e9c620)
在想要如何測試
測試一個菱形的DAG
TangleRoot:
```
ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999
```
發起一筆新的 , 直接驗證到 TangleRoot
```
9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999
```
看測試的結果
nodes:
```
(2) [{…}, {…}]
0
:
height
:
0
name
:
"ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999"
nodeIndex
:
0
__proto__
:
Object
1
:
height
:
1
name
:
"9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999"
nodeIndex
:
1
__proto__
:
Object
length
:
2
__proto__
:
Array(0)
```
links:
```
:
source
:
{name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1}
target
:
{name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0}
__proto__
:
Object
length
:
1
__proto__
:
Array(0)
```
再發一筆驗證到 TangleRoot的交易
```
WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999
```
看測試的結果
nodes:
```
(3) [{…}, {…}, {…}]
0
:
{name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0}
1
:
{name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1}
2
:
{name: "WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999", height: 1, nodeIndex: 2}
length
:
3
__proto__
:
Array(0)
```
links:
```
(2) [{…}, {…}]
0:
source:{name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1}
target:{name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0}
__proto__
:
Object
1:
source:{name: "WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999", height: 1, nodeIndex: 2}
target:{name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0}
__proto__
:
Object
length
:
2
__proto__
:
Array(0)
```
所以有兩筆指向 tangleRoot
而 links 所紀錄的指向關係也沒錯
現在再發一筆交易 , 指向 "WW9..." 與 "9QV..."
交易 hash:
```
HZGTOLSBLMJGFWRGPOJOKUDLFTJDNSLTJOORCSIWKHTNJGOYDVDGWPXTZXZNPVFALIOOXOXPZYBE99999
```
發現 links 的數量不對
進一步追查是 doesLinkExist 不會被賦值為1
代表檢查 link 有沒有在 links 有問題
修改了檢查 links 的 [code](https://github.com/DLTcollab/tangle-analytics/commit/ba0b4096c362851cbf1d293e33b5ce9e1987d57d):
```javascript=
for(let Link of Links){
if(Link.source == Nodes[approverNodeIndex] && Link.target == searchedTransaction){
doesLinkExist = 1;
}
}
```
重新測試菱形的情況
nodes:
```
(4) [{…}, {…}, {…}, {…}]
0
:
{name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0}
1
:
{name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1}
2
:
{name: "WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999", height: 1, nodeIndex: 2}
3
:
{name: "HZGTOLSBLMJGFWRGPOJOKUDLFTJDNSLTJOORCSIWKHTNJGOYDVDGWPXTZXZNPVFALIOOXOXPZYBE99999", height: 2, nodeIndex: 3}
length
:
4
```
links:
```
(4) [{…}, {…}, {…}, {…}]
0
:
source:{name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1}
target:{name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0}
__proto__
:
Object
1
:
source:{name: "WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999", height: 1, nodeIndex: 2}
target:{name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0}
__proto__
:
Object
2
:
source:{name: "HZGTOLSBLMJGFWRGPOJOKUDLFTJDNSLTJOORCSIWKHTNJGOYDVDGWPXTZXZNPVFALIOOXOXPZYBE99999", height: 2, nodeIndex: 3}
target:{name: "WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999", height: 1, nodeIndex: 2}
__proto__
:
Object
3
:
source:{name: "HZGTOLSBLMJGFWRGPOJOKUDLFTJDNSLTJOORCSIWKHTNJGOYDVDGWPXTZXZNPVFALIOOXOXPZYBE99999", height: 2, nodeIndex: 3}
target:{name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1}
__proto__
:
Object
length
:
4
```
links 也沒有重複的元素 , 且都紀錄到了正確的驗證關係
又多送直接驗證到 “WW9…” 與 “9QV…” 的交易
一樣沒錯

測試用的[TangleRoot](https://thetangle.org/transaction/ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999)
# 1/24
開始處理 Tangle 的[顯示](https://hackmd.io/s/HJmfL5c0f#subtangle)
構想如下

用 redux 傳 nodes 與 links
然後 TangleContainer 要包含控制顯示的部份
舉個例子
```graphviz
digraph init{
rankdir=RL;
a[ label="c" color=yellow, fontcolor=yellow, fontsize=24, shape=box style = filled];
b[label="C1" color=black, fontcolor=red, fontsize=24, shape=box ];
c[label="C1" color=green, fontcolor=red, fontsize=24, shape=box style = filled]
e[label="e" color=green, fontcolor=green, fontsize=24, shape=box style = filled]
d[label="B3" color=black, fontcolor=blue, fontsize=24, shape=box]
21[label="" color=black, fontcolor=blue, fontsize=24, shape=box]
11[label="" color=yellow, fontcolor=yellow, fontsize=24, shape=box style = filled]
31[label="B2" color=black, fontcolor=blue, fontsize=24, shape=box]
22[label="" color=black, fontcolor=blue, fontsize=24, shape=box]
12[label="" color=black, fontcolor=blue, fontsize=24, shape=box]
32[label="" color=black, fontcolor=blue, fontsize=24, shape=box]
41[label="" color=black, fontcolor=blue, fontsize=24, shape=box]
23[label="" color=gray, fontcolor=black, fontsize=24, shape=box style = filled]
13[label="" color=gray, fontcolor=blue, fontsize=24, shape=box style = filled]
42[label="B1" color=black, fontcolor=blue, fontsize=24, shape=box]
33[label="" color=gray, fontcolor=blue, fontsize=24, shape=box style = filled]
a -> c;
b -> c;
a -> c;
b -> c;
e -> a;
e -> a;
d -> a;
d -> b;
21->e;
21->d;
11->e;
11->e;
31->d;
31->d;
22->21;
22->31;
41->e;
41->d;
12->11;
12->21;
32->21;
32->31;
23->22;
23->32;
42->41;
42->31;
13->12;
13->22;
33->22;
33->42;
}
```
以上是全部標示
可以選擇不讓 milestone 顯示出來
那黃色的交易就會變成白色
目前先讓 Redux 可以正確運作
[Redux基礎](https://chentsulin.github.io/redux/docs/basics/index.html)
# 1/25
發現更簡單的作法:[helper class](https://medium.com/@chachameow/reactjs%E5%AD%B8%E7%BF%92%E7%AD%86%E8%A8%98-component%E9%96%93%E5%82%B3%E5%80%BC-53fbd469132e)
先用這個方法來處理
新的 [commit](https://github.com/DLTcollab/tangle-analytics/commit/7a73c64fd6c2c29089959d89eee448aa003790a9)
結果:

nodes 和 links 有正確傳給 TangleContainer
但由於每個 node 的 x,y 座標沒給 , 所以圖畫不出來
現在會先來改寫 TangleContainer , 把控制顯示與 d3 加進去
# 2/15
考慮重寫 GetNextApprovees
格式想重新定義
理由是這樣的
由於 Tangle 繪圖是依賴 nodes 和 links , 而原本的 nodes 會被修改 , 以便在畫 rect 時可以根據顯示條件來做更改
例如要不要標示交易是否確認
所以 links 也會要做更改
既然是跟顯示相關
TangleManagementContainer也不需要 links
而是紀錄交易 list
丟給 TangleContainer
TangleContainer 在依據顯示的要求 , 去生成 nodes 與 links
###### tags: `IOTA`