Sankey data generated in backend, not yet showed correctly in frontend
arnaucode idoctnef@openmailbox.org
Fri, 28 Jul 2017 01:31:45 +0200
12 files changed,
205 insertions(+),
25 deletions(-)
M
README.md
→
README.md
@@ -1,11 +1,70 @@
# goBlockchainDataAnalysis blockchain data analysis, written in Go +### Install +1. Nodejs & NPM https://nodejs.org/ +2. MongoDB https://www.mongodb.com/ +3. Faircoin wallet https://download.faircoin.world/ +4. goBlockchainDataAnalysis https://github.com/arnaucode/goBlockchainDataAnalysis +### Configure +- Wallet /home/user/.faircoin2/faircoin.conf: +``` +rpcuser=usernamerpc +rpcpassword=password +rpcport=3021 +rpcworkqueue=2000 +server=1 +rpcbind=127.0.0.1 +rpcallowip=127.0.0.1 +``` -## Run +- goBlockchainDataAnalysis/config.json: +```json +{ + "user": "usernamerpc", + "pass": "password", + "host": "127.0.0.1", + "port": "3021", + "genesisTx": "7c27ade2c28e67ed3077f8f77b8ea6d36d4f5eba04c099be3c9faa9a4a04c046", + "genesisBlock": "beed44fa5e96150d95d56ebd5d2625781825a9407a5215dd7eda723373a0a1d7" +} +``` + +### Run + +1. Start MongoDB +``` +sudo service mongod start +``` -- First run explorer +2. Start wallet +``` +./faircoind -txindex -reindex-chainstate +``` + +3. Run explorer, to fill the database ``` ./goBlockchainDataAnalysis -explore ``` + + 3.1. The next runs, once the database have data, can just run: +``` +./goBlockchainDataAnalysis +``` + +4. Run the webserver, in the /web directory +``` +npm start +``` +Webapp will run on 127.0.0.1:8080 + + + +### Additional info +- Backend + - Go lang https://golang.org/ + - MongoDB https://www.mongodb.com/ +- Frontend + - AngularJS https://angularjs.org/ + - Angular-Bootstrap-Material https://tilwinjoy.github.io/angular-bootstrap-material
M
mongoModels.go
→
mongoModels.go
@@ -28,7 +28,7 @@ type EdgeModel struct {
Txid string `json:"txid"` From string `json:"from"` To string `json:"to"` - Label float64 `json:"label"` + Label float64 `json:"label"` //the value of transaction Arrows string `json:"arrows"` BlockHeight int64 `json:"blockheight"` }@@ -36,3 +36,20 @@ type NetworkModel struct {
Nodes []NodeModel `json:"nodes"` Edges []EdgeModel `json:"edges"` } + +type SankeyNodeModel struct { + //StringNode string `json:"stringnode"` + Node int `json:"node"` + Name string `json:"name"` +} +type SankeyLinkModel struct { + //StringSource string `json:"stringsource"` + Source int `json:"source"` + //StringTarget string `json:"stringtarget"` + Target int `json:"target"` + Value float64 `json:"value"` +} +type SankeyModel struct { + Nodes []SankeyNodeModel `json:"nodes"` + Links []SankeyLinkModel `json:"links"` +}
M
serverRoutes.go
→
serverRoutes.go
@@ -32,6 +32,12 @@ "/address/network/{address}",
AddressNetwork, }, Route{ + "AddressSankey", + "GET", + "/address/sankey/{address}", + AddressSankey, + }, + Route{ "NetworkMap", "Get", "/map",@@ -97,6 +103,45 @@ jNetwork, err := json.Marshal(network)
check(err) fmt.Fprintln(w, string(jNetwork)) + } +} +func AddressSankey(w http.ResponseWriter, r *http.Request) { + ipFilter(w, r) + + vars := mux.Vars(r) + address := vars["address"] + if address == "undefined" { + fmt.Fprintln(w, "not valid address") + } else { + network := addressTree(address) + var sankey SankeyModel + + fmt.Println("network generated") + mapNodeK := make(map[string]int) + for k, n := range network.Nodes { + var sankeyNode SankeyNodeModel + //sankeyNode.StringNode = n.Id + sankeyNode.Node = k + sankeyNode.Name = n.Id + sankey.Nodes = append(sankey.Nodes, sankeyNode) + mapNodeK[n.Id] = k + } + for _, e := range network.Edges { + var sankeyLink SankeyLinkModel + //sankeyLink.StringSource = e.From + sankeyLink.Source = mapNodeK[e.From] + //sankeyLink.StringTarget = e.To + sankeyLink.Target = mapNodeK[e.To] + sankeyLink.Value = e.Label + 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 NetworkMap(w http.ResponseWriter, r *http.Request) {
M
web/bower.json
→
web/bower.json
@@ -1,19 +1,19 @@
{ - "name": "goBlockchainDataAnalysis", - "description": "goBlockchainDataAnalysis", - "version": "0.0.0", - "homepage": "https://github.com/arnaucode/goBlockchainDataAnalysis", - "license": "MIT", - "private": true, - "dependencies": { - "angular": "^1.6.2", - "angular-route": "^1.6.1", - "angular-chart.js": "^1.1.1", - "vis": "^4.18.1", - "mui": "^0.9.20", - "angular-bootstrap-material": "abm#^0.1.4", - "angular-bootstrap": "^2.5.0", - "angular-messages": "^1.6.5", - "components-font-awesome": "^4.7.0" - } + "name": "goBlockchainDataAnalysis", + "description": "goBlockchainDataAnalysis", + "version": "0.0.0", + "homepage": "https://github.com/arnaucode/goBlockchainDataAnalysis", + "license": "MIT", + "private": true, + "dependencies": { + "angular": "^1.6.2", + "angular-route": "^1.6.1", + "angular-chart.js": "^1.1.1", + "vis": "^4.18.1", + "angular-bootstrap-material": "abm#^0.1.4", + "angular-bootstrap": "^2.5.0", + "angular-messages": "^1.6.5", + "components-font-awesome": "^4.7.0", + "sankeyjs": "^1.2.2" + } }
M
web/index.html
→
web/index.html
@@ -77,6 +77,10 @@ <!-- Angular Chart -->
<script src="bower_components/chart.js/dist/Chart.min.js"></script> <script src="bower_components/angular-chart.js/dist/angular-chart.min.js"></script> + <!-- d3js --> + <script src="https://d3js.org/d3.v3.min.js" charset="utf-8" type="text/javascript"></script> + <script src="bower_components/sankeyjs/dist/d3.sankey.js" charset="utf-8" type="text/javascript"></script> + <script src="bower_components/sankeyjs/dist/d3.sankey.directive.js" charset="utf-8" type="text/javascript"></script> <!-- visjs --> <script type="text/javascript" src="bower_components/vis/dist/vis.min.js"></script>
M
web/views/addressNetwork/addressNetwork.html
→
web/views/addressNetwork/addressNetwork.html
@@ -19,7 +19,7 @@ </div>
</div> <div class="col-sm-9"> <div class="panel-heading c_blueGrey300"> - <h3 class="panel-title">Network</h3> + <h3 class="panel-title">Address history Network Map</h3> </div> <div class="panel-body"> <div id="mynetwork" style="height:800px;"></div>
M
web/views/sankey/sankey.html
→
web/views/sankey/sankey.html
@@ -1,11 +1,28 @@
<div class="container"> <div class="row"> - <div class="col-sm-12"> + <div class="col-sm-2"> + <div class="panel-heading c_blueGrey300"> + <h3 class="panel-title">All addresses</h3> + </div> + <div class="panel-body" style="max-height: 500px;overflow-y: scroll;"> + <div class="form-group label-floating"> + <input ng-model="filterAddress" abmFormControl class="form-control" placeholder="Filter" type="text"> + </div> + <div ng-click="getAddressSankey(node)" class="list-group-item" ng-repeat="node in addresses | filter: filterAddress"> + <div class="row-content"> + <p class="list-group-item-text">{{node.id}}</p> + + <!--<p class="list-group-item-text">Maecenas sed diam eget risus varius blandit.</p>--> + </div> + </div> + </div> + </div> + <div class="col-sm-10"> <div class="panel-heading c_blueGrey300"> <h3 class="panel-title">Sankey</h3> </div> <div class="panel-body"> - + <ng-sankey id="sankeyChart" options="options" data="data"></ng-sankey> </div> </div> </div>
M
web/views/sankey/sankey.js
→
web/views/sankey/sankey.js
@@ -1,6 +1,6 @@
'use strict'; -angular.module('app.sankey', ['ngRoute']) +angular.module('app.sankey', ['ngRoute', 'ngSankey']) .config(['$routeProvider', function($routeProvider) { $routeProvider.when('/sankey', {@@ -10,6 +10,43 @@ });
}]) .controller('SankeyCtrl', function($scope, $http, $routeParams) { - + + $scope.options = { + chart: '#sankeyChart', + width: 960, + height: 500, + 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 + 'alladdresses') + .then(function(data, status, headers, config) { + console.log('data success'); + console.log(data); + $scope.addresses = data.data; + }, function(data, status, headers, config) { + console.log('data error'); + }); + $scope.getAddressSankey = function(address) { + console.log(address); + $http.get(urlapi + 'address/sankey/' + address.id) + .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); + let chart = new d3.sankeyChart(data.data, $scope.options); + //$scope.data = data.data; + }, function(data, status, headers, config) { + console.log('data error'); + }); + }; });