Browse Source

implemented sankey of block.txs[] and from tx, in frontend and backend

master
arnaucode 7 years ago
parent
commit
9092aea11b
7 changed files with 228 additions and 4 deletions
  1. +3
    -0
      DevelopmentNotes.md
  2. BIN
      goBlockchainDataAnalysis
  3. +145
    -0
      serverRoutes.go
  4. +6
    -3
      web/views/block/block.html
  5. +31
    -1
      web/views/block/block.js
  6. +15
    -0
      web/views/tx/tx.html
  7. +28
    -0
      web/views/tx/tx.js

+ 3
- 0
DevelopmentNotes.md

@ -30,3 +30,6 @@ other
- mantain connection with wallet using websockets - mantain connection with wallet using websockets
- num address evolution throught time - 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

BIN
goBlockchainDataAnalysis


+ 145
- 0
serverRoutes.go

@ -70,6 +70,18 @@ var routes = Routes{
"/address/network/{address}", "/address/network/{address}",
AddressNetwork, AddressNetwork,
}, },
Route{
"BlockSankey",
"GET",
"/block/{height}/sankey",
BlockSankey,
},
Route{
"TxSankey",
"GET",
"/tx/{txid}/sankey",
TxSankey,
},
Route{ Route{
"AddressSankey", "AddressSankey",
"GET", "GET",
@ -275,6 +287,139 @@ func AddressNetwork(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, string(jNetwork)) 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) { func AddressSankey(w http.ResponseWriter, r *http.Request) {
ipFilter(w, r) ipFilter(w, r)
vars := mux.Vars(r) vars := mux.Vars(r)

+ 6
- 3
web/views/block/block.html

@ -15,10 +15,13 @@
<div class="col-sm-8"> <div class="col-sm-8">
<div class="panel"> <div class="panel">
<div class="panel-heading c_deepPurpleG300to500"> <div class="panel-heading c_deepPurpleG300to500">
<h3 class="panel-title">Block evolution</h3>
<h3 class="panel-title">Block transactions flow</h3>
</div> </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> </div>
</div> </div>

+ 31
- 1
web/views/block/block.js

@ -1,6 +1,6 @@
'use strict'; 'use strict';
angular.module('app.block', ['ngRoute'])
angular.module('app.block', ['ngRoute', 'ngSankey'])
.config(['$routeProvider', function($routeProvider) { .config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/block/:height', { $routeProvider.when('/block/:height', {
@ -18,4 +18,34 @@ angular.module('app.block', ['ngRoute'])
}, function(data, status, headers, config) { }, function(data, status, headers, config) {
console.log('data error'); 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');
});
}); });

+ 15
- 0
web/views/tx/tx.html

@ -45,3 +45,18 @@
</div> </div>
</div> </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>

+ 28
- 0
web/views/tx/tx.js

@ -18,4 +18,32 @@ angular.module('app.tx', ['ngRoute'])
}, function(data, status, headers, config) { }, function(data, status, headers, config) {
console.log('data error'); 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');
});
}); });

Loading…
Cancel
Save