mirror of
https://github.com/arnaucube/goBlockchainDataAnalysis.git
synced 2026-02-06 19:26:41 +01:00
implemented sankey of block.txs[] and from tx, in frontend and backend
This commit is contained in:
@@ -30,3 +30,6 @@ other
|
||||
- mantain connection with wallet using websockets
|
||||
|
||||
- num address evolution throught time
|
||||
|
||||
- fix error in exploreBlockchain.go, when getting the tx.Vin
|
||||
tx 8f04960da36beaa928b9693f7dca4afae5a6122bb6874d409a1156e4c6c55024 has 4 vin, but exploreBlockchain is only getting the first
|
||||
|
||||
Binary file not shown.
145
serverRoutes.go
145
serverRoutes.go
@@ -70,6 +70,18 @@ var routes = Routes{
|
||||
"/address/network/{address}",
|
||||
AddressNetwork,
|
||||
},
|
||||
Route{
|
||||
"BlockSankey",
|
||||
"GET",
|
||||
"/block/{height}/sankey",
|
||||
BlockSankey,
|
||||
},
|
||||
Route{
|
||||
"TxSankey",
|
||||
"GET",
|
||||
"/tx/{txid}/sankey",
|
||||
TxSankey,
|
||||
},
|
||||
Route{
|
||||
"AddressSankey",
|
||||
"GET",
|
||||
@@ -275,6 +287,139 @@ func AddressNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, string(jNetwork))
|
||||
}
|
||||
}
|
||||
func BlockSankey(w http.ResponseWriter, r *http.Request) {
|
||||
ipFilter(w, r)
|
||||
vars := mux.Vars(r)
|
||||
var heightString string
|
||||
heightString = vars["height"]
|
||||
height, err := strconv.ParseInt(heightString, 10, 64)
|
||||
if err != nil {
|
||||
fmt.Fprintln(w, "not valid height")
|
||||
} else {
|
||||
block := BlockModel{}
|
||||
err := blockCollection.Find(bson.M{"height": height}).One(&block)
|
||||
|
||||
txs := []TxModel{}
|
||||
err = txCollection.Find(bson.M{"blockheight": heightString}).All(&txs)
|
||||
block.Txs = txs
|
||||
|
||||
var nodesCount int
|
||||
mapNodeK := make(map[string]int)
|
||||
var sankey SankeyModel
|
||||
for _, tx := range block.Txs {
|
||||
var sankeyNodeA SankeyNodeModel
|
||||
sankeyNodeA.Node = nodesCount
|
||||
mapNodeK["tx"] = nodesCount
|
||||
nodesCount++
|
||||
sankeyNodeA.Name = "tx"
|
||||
sankey.Nodes = append(sankey.Nodes, sankeyNodeA)
|
||||
|
||||
for _, vin := range tx.Vin {
|
||||
var sankeyNode SankeyNodeModel
|
||||
sankeyNode.Node = nodesCount
|
||||
mapNodeK[vin.Address] = nodesCount
|
||||
nodesCount++
|
||||
sankeyNode.Name = vin.Address
|
||||
sankey.Nodes = append(sankey.Nodes, sankeyNode)
|
||||
|
||||
var sankeyLink SankeyLinkModel
|
||||
sankeyLink.Source = mapNodeK[vin.Address]
|
||||
sankeyLink.Target = mapNodeK["tx"]
|
||||
sankeyLink.Value = vin.Amount
|
||||
fmt.Println(sankeyLink)
|
||||
sankey.Links = append(sankey.Links, sankeyLink)
|
||||
fmt.Println(sankey.Links)
|
||||
}
|
||||
|
||||
for _, vout := range tx.Vout {
|
||||
var sankeyNode SankeyNodeModel
|
||||
sankeyNode.Node = nodesCount
|
||||
mapNodeK[vout.Address] = nodesCount
|
||||
nodesCount++
|
||||
sankeyNode.Name = vout.Address
|
||||
sankey.Nodes = append(sankey.Nodes, sankeyNode)
|
||||
|
||||
var sankeyLink SankeyLinkModel
|
||||
sankeyLink.Source = mapNodeK["tx"]
|
||||
sankeyLink.Target = mapNodeK[vout.Address]
|
||||
sankeyLink.Value = vout.Value
|
||||
fmt.Println(sankeyLink)
|
||||
sankey.Links = append(sankey.Links, sankeyLink)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fmt.Println("Sankey generated")
|
||||
fmt.Println(sankey)
|
||||
|
||||
//convert []resp struct to json
|
||||
jsonSankey, err := json.Marshal(sankey)
|
||||
check(err)
|
||||
|
||||
fmt.Fprintln(w, string(jsonSankey))
|
||||
}
|
||||
}
|
||||
func TxSankey(w http.ResponseWriter, r *http.Request) {
|
||||
ipFilter(w, r)
|
||||
vars := mux.Vars(r)
|
||||
txid := vars["txid"]
|
||||
if txid == "undefined" {
|
||||
fmt.Fprintln(w, "not valid height")
|
||||
} else {
|
||||
|
||||
tx := TxModel{}
|
||||
err := txCollection.Find(bson.M{"txid": txid}).One(&tx)
|
||||
|
||||
var nodesCount int
|
||||
mapNodeK := make(map[string]int)
|
||||
var sankey SankeyModel
|
||||
var sankeyNodeA SankeyNodeModel
|
||||
sankeyNodeA.Node = nodesCount
|
||||
mapNodeK["tx"] = nodesCount
|
||||
nodesCount++
|
||||
sankeyNodeA.Name = "tx"
|
||||
sankey.Nodes = append(sankey.Nodes, sankeyNodeA)
|
||||
|
||||
fmt.Println(tx.Vin)
|
||||
for _, vin := range tx.Vin {
|
||||
var sankeyNode SankeyNodeModel
|
||||
sankeyNode.Node = nodesCount
|
||||
mapNodeK[vin.Address] = nodesCount
|
||||
nodesCount++
|
||||
sankeyNode.Name = vin.Address
|
||||
sankey.Nodes = append(sankey.Nodes, sankeyNode)
|
||||
|
||||
var sankeyLink SankeyLinkModel
|
||||
sankeyLink.Source = mapNodeK[vin.Address]
|
||||
sankeyLink.Target = mapNodeK["tx"]
|
||||
sankeyLink.Value = vin.Amount
|
||||
sankey.Links = append(sankey.Links, sankeyLink)
|
||||
}
|
||||
|
||||
for _, vout := range tx.Vout {
|
||||
var sankeyNode SankeyNodeModel
|
||||
sankeyNode.Node = nodesCount
|
||||
mapNodeK[vout.Address] = nodesCount
|
||||
nodesCount++
|
||||
sankeyNode.Name = vout.Address
|
||||
sankey.Nodes = append(sankey.Nodes, sankeyNode)
|
||||
|
||||
var sankeyLink SankeyLinkModel
|
||||
sankeyLink.Source = mapNodeK["tx"]
|
||||
sankeyLink.Target = mapNodeK[vout.Address]
|
||||
sankeyLink.Value = vout.Value
|
||||
sankey.Links = append(sankey.Links, sankeyLink)
|
||||
}
|
||||
|
||||
fmt.Println("Sankey generated")
|
||||
|
||||
//convert []resp struct to json
|
||||
jsonSankey, err := json.Marshal(sankey)
|
||||
check(err)
|
||||
|
||||
fmt.Fprintln(w, string(jsonSankey))
|
||||
}
|
||||
}
|
||||
func AddressSankey(w http.ResponseWriter, r *http.Request) {
|
||||
ipFilter(w, r)
|
||||
vars := mux.Vars(r)
|
||||
|
||||
@@ -15,10 +15,13 @@
|
||||
<div class="col-sm-8">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Block evolution</h3>
|
||||
<h3 class="panel-title">Block transactions flow</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="panel-body" style="height: 300px;overflow-y: hidden;">
|
||||
<div id="sankeyChart">
|
||||
<canvas></canvas>
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app.block', ['ngRoute'])
|
||||
angular.module('app.block', ['ngRoute', 'ngSankey'])
|
||||
|
||||
.config(['$routeProvider', function($routeProvider) {
|
||||
$routeProvider.when('/block/:height', {
|
||||
@@ -18,4 +18,34 @@ angular.module('app.block', ['ngRoute'])
|
||||
}, function(data, status, headers, config) {
|
||||
console.log('data error');
|
||||
});
|
||||
|
||||
|
||||
//Sankey
|
||||
$scope.options = {
|
||||
chart: '#sankeyChart',
|
||||
width: 700,
|
||||
height: 280,
|
||||
margin: {top: 1, right: 1, bottom: 6, left: 1},
|
||||
node: {width: 15, padding :10, showValue: false},
|
||||
value: {format: ',.0f', unit : ''},
|
||||
dynamicLinkColor: true,
|
||||
trafficInLinks: true
|
||||
};
|
||||
$scope.data={
|
||||
nodes: [],
|
||||
links: []
|
||||
};
|
||||
$http.get(urlapi + 'block/' + $routeParams.height + '/sankey')
|
||||
.then(function(data, status, headers, config) {
|
||||
console.log('data success');
|
||||
console.log(data);
|
||||
$scope.data.nodes = data.data.nodes;
|
||||
$scope.data.links = data.data.links;
|
||||
console.log($scope.data);
|
||||
d3.selectAll("svg > *").remove();
|
||||
let chart = new d3.sankeyChart(data.data, $scope.options);
|
||||
//$scope.data = data.data;
|
||||
}, function(data, status, headers, config) {
|
||||
console.log('data error');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,3 +45,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Transaction flow</h3>
|
||||
</div>
|
||||
<div class="panel-body" style="height: 300px;overflow-y: hidden;">
|
||||
<div id="sankeyChart">
|
||||
<canvas></canvas>
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -18,4 +18,32 @@ angular.module('app.tx', ['ngRoute'])
|
||||
}, function(data, status, headers, config) {
|
||||
console.log('data error');
|
||||
});
|
||||
//Sankey
|
||||
$scope.options = {
|
||||
chart: '#sankeyChart',
|
||||
width: 1000,
|
||||
height: 280,
|
||||
margin: {top: 1, right: 1, bottom: 6, left: 1},
|
||||
node: {width: 15, padding :10, showValue: false},
|
||||
value: {format: ',.0f', unit : ''},
|
||||
dynamicLinkColor: true,
|
||||
trafficInLinks: true
|
||||
};
|
||||
$scope.data={
|
||||
nodes: [],
|
||||
links: []
|
||||
};
|
||||
$http.get(urlapi + 'tx/' + $routeParams.txid + '/sankey')
|
||||
.then(function(data, status, headers, config) {
|
||||
console.log('data success');
|
||||
console.log(data);
|
||||
$scope.data.nodes = data.data.nodes;
|
||||
$scope.data.links = data.data.links;
|
||||
console.log($scope.data);
|
||||
d3.selectAll("svg > *").remove();
|
||||
let chart = new d3.sankeyChart(data.data, $scope.options);
|
||||
//$scope.data = data.data;
|
||||
}, function(data, status, headers, config) {
|
||||
console.log('data error');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user