Charts with the BGE-API and dimplejs

Finally it is out! For almost two months we promised it. Due to some open issues in the real life, it was not easy to find spare time to work on it, but finally it is done!

We are proud to present you the first examples of charts using Bitcoin-Graph-Explorer API and dimple.js. Dimple is a Library that uses d3 and exposes a simplified usage of d3.

First of all we need to include d3 and dimple in our page, and jquery for simplicity of the ajax calls:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js">
<script src="http://d3js.org/d3.v3.min.js"/>
<script src="http://dimplejs.org/dist/dimple.v2.1.6.min.js"/>

With all that included, now we can start using the BGE server:

Retrieving transactions pro block

In our first example we are going to retrieve first the current block height and when we got it, we ask the server for the last 100 blocks:

function requestData(){
    const request1 = jQuery.ajax( {
      url: "https://api.bitcoinprivacy.net/stats", 
      dataType: "json"
    });
    request1.done(function(json){
      const bh = json.block_height;
      const request2 = jQuery.ajax( {
        url: "https://api.bitcoinprivacy.net/blocks/"+(bh-100)+"/"+bh, 
        dataType: "json"
      });
    request2.done(function(json){
    drawChart(json);
  });

  request2.fail(function(jqXHR, textStatus){ 
    alert("error2"); });
  });
  request1.fail(function(jqXHR, textStatus){ 
    alert("error1"); 
  });
}

And to represent it we draw a area chart using dimple

function drawChart(json){
  var svg = dimple.newSvg("#chart", 600, 400);
  var chart = new dimple.chart(svg, json);
  var x = chart.addCategoryAxis("x", "height");
  x.hidden = true;
  var y = chart.addMeasureAxis("y", "tx");
  y.title = "Transactionen pro Block";
  chart.addSeries(null, dimple.plot.area);
  chart.draw();
}

Here you can see the code in action:

http://jsfiddle.net/9pe9nufa/

Get outputs from an address

Now we are trying to retrieve information about an address, the set of outputs, both expended and unexpended:

function requestData(){
  var address = "1JCe8z4jJVNXSjohjM4i9Hh813dLCNx2Sy";
  var request1 = jQuery.ajax({
    url: "https://api.bitcoinprivacy.net/utxos/"+address+"/0/1000", 
    dataType: "json"
  });
  var request2 = jQuery.ajax({
    url: "https://api.bitcoinprivacy.net/movements/"+address+"/0/1000", 
    dataType: "json"
  });
  var result1 = false;
  var result2 = false;
  request1.done(function(j){ 
    result1 = j; 
    if (result1 && result2) 
      drawChart(result1, result2); 
  });
  request2.done(function(j){ 
    result2 = j; 
    if (result1 && result2) 
      drawChart(result1, result2); 
  });
  request1.fail(function(jqXHR, textStatus){ alert("error"); });
  request2.fail(function(jqXHR, textStatus){ alert("error"); });
}

and now the draw function. We will display this time bubbles, red for representing spend outputs and blue for unspent.

function drawChart(utxos, moves){
  var svg = dimple.newSvg("#chart", 600, 400);
  var data = [];
  for (i=0;i<utxos.length;i++){
    data.push({value:utxos[i].value/100000000, status:"unspend", tx:utxos[i].tx});
  }
  for (i=0;i<moves.length;i++){
    data.push({value:moves[i].value/100000000, status:"spend", tx:moves[i].tx});
  }
  var myChart = new dimple.chart(svg, data);
  myChart.setBounds(95, 25, 475, 335)
  myChart.addCategoryAxis("x", "tx");
  myChart.addCategoryAxis("y", "status");
  myChart.addMeasureAxis("z", "value");
  myChart.addSeries("status", dimple.plot.bubble);
  myChart.addLegend(240, 10, 330, 20, "right");
  myChart.draw();
}

To see the code working:

http://jsfiddle.net/0yu98cjz/

Obtain wealth distribution

Now last example is to show the % of addresses containing bitcoins with amount in intervals,

function requestData(){
  var request1 = jQuery.ajax( {
    url: "https://api.bitcoinprivacy.net/distribution/1000000000000", 
    dataType: "json"
  } );
  var request2 = jQuery.ajax( {
    url: "https://api.bitcoinprivacy.net/distribution/100000000000", 
    dataType: "json"
  });
  var request3 = jQuery.ajax( {
    url: "https://api.bitcoinprivacy.net/distribution/10000000000", 
    dataType: "json"} );
  var request4 = jQuery.ajax( {
    url: "https://api.bitcoinprivacy.net/distribution/1000000000", 
    dataType: "json"} );
  var request5 = jQuery.ajax( {
    url: "https://api.bitcoinprivacy.net/distribution/100000000", 
    dataType: "json"} );
  var request6 = jQuery.ajax( {
    url: "https://api.bitcoinprivacy.net/distribution/10000000", 
    dataType: "json"} );
  var result1 = result2 = result3 = result4 = result5 = result6 = false;
  var addData = function(){
    if (result1&&result2&&result3&&result4&&result5&&result6){
      drawChart(result1,result2,result3,result4,result5,result6);
    }
  }
  request1.done(function(j){ result1 = j; addData();});
  request2.done(function(j){ result2 = j; addData();});
  request3.done(function(j){ result3 = j; addData();});
  request4.done(function(j){ result4 = j; addData();});
  request5.done(function(j){ result5 = j; addData();});
  request6.done(function(j){ result6 = j; addData();});
  request1.fail(function(jqXHR, textStatus){ console.log("error"); });
  request2.fail(function(jqXHR, textStatus){ console.log("error"); });
  request3.fail(function(jqXHR, textStatus){ console.log("error"); });
  request4.fail(function(jqXHR, textStatus){ console.log("error"); });
  request5.fail(function(jqXHR, textStatus){ console.log("error"); });
  request6.fail(function(jqXHR, textStatus){ console.log("error"); });
}

To represent this information we can choice a simple bar diagram, and to render it using dimple:

function drawChart(r10000,r1000,r100,r10,r1,r01){
  var svg = dimple.newSvg("#chart", 600, 400);
  var data = [
    {count:r10000.addresses, value:10000},
    {count:r1000.addresses-r10000.addresses, value:1000},
    {count:r100.addresses-r1000.addresses, value:100},
    {count:r10.addresses-r100.addresses, value:10},
    {count:r1.addresses-r10.addresses, value:1},
    {count:r01.addresses-r1.addresses, value:0.1}
  ];
  var myChart = new dimple.chart(svg, data);
  myChart.setBounds(95, 25, 475, 335)
  var y = myChart.addMeasureAxis("y", "count");
  y.title = "Addresses per interval"
  var x = myChart.addCategoryAxis("x", "value");
  x.title = "Bitcoin intervals"
  myChart.addSeries(null, dimple.plot.bar);
  myChart.draw();
}

To see how the code works:

http://jsfiddle.net/8z9yvkzt/

For more ideas, below a list with examples of all possible requests:

https://api.bitcoinprivacy.net/blocks/100/200

https://api.bitcoinprivacy.net/blocks/summary

https://api.bitcoinprivacy.net/distribution/10

https://api.bitcoinprivacy.net/inputs/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/0/100

https://api.bitcoinprivacy.net/inputs/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/summary

https://api.bitcoinprivacy.net/movements/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/movements/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/outputs/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/0/100

https://api.bitcoinprivacy.net/outputs/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/summary

https://api.bitcoinprivacy.net/richlist/addresses/443485/0/100

https://api.bitcoinprivacy.net/richlist/addresses/443485/summary

https://api.bitcoinprivacy.net/richlist/wallets/443485/0/100

https://api.bitcoinprivacy.net/richlist/wallets/443485/summary

https://api.bitcoinprivacy.net/stats

https://api.bitcoinprivacy.net/stats/history

https://api.bitcoinprivacy.net/tx_utxos/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/0/100

https://api.bitcoinprivacy.net/tx_utxos/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/summary

https://api.bitcoinprivacy.net/txs/443485/0/100

https://api.bitcoinprivacy.net/txs/443485/summary

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/tx_utxos/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/summary

https://api.bitcoinprivacy.net/txs/443485/0/100

https://api.bitcoinprivacy.net/txs/443485/summary

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/tx_utxos/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/0/100

https://api.bitcoinprivacy.net/tx_utxos/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/summary

https://api.bitcoinprivacy.net/txs/443485/0/100

https://api.bitcoinprivacy.net/txs/443485/summary

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/tx_utxos/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/summary

https://api.bitcoinprivacy.net/txs/443485/0/100

https://api.bitcoinprivacy.net/txs/443485/summary

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/movements/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/movements/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/outputs/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/0/100

https://api.bitcoinprivacy.net/outputs/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/summary

https://api.bitcoinprivacy.net/richlist/addresses/443485/0/100

https://api.bitcoinprivacy.net/richlist/addresses/443485/summary

https://api.bitcoinprivacy.net/richlist/wallets/443485/0/100

https://api.bitcoinprivacy.net/richlist/wallets/443485/summary

https://api.bitcoinprivacy.net/stats

https://api.bitcoinprivacy.net/stats/history

https://api.bitcoinprivacy.net/tx_utxos/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/0/100

https://api.bitcoinprivacy.net/tx_utxos/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/summary

https://api.bitcoinprivacy.net/txs/443485/0/100

https://api.bitcoinprivacy.net/txs/443485/summary

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/distribution/10

https://api.bitcoinprivacy.net/inputs/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/0/100

https://api.bitcoinprivacy.net/inputs/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/summary

https://api.bitcoinprivacy.net/movements/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/movements/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/outputs/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/0/100

https://api.bitcoinprivacy.net/outputs/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/summary

https://api.bitcoinprivacy.net/richlist/addresses/443485/0/100

https://api.bitcoinprivacy.net/richlist/addresses/443485/summary

https://api.bitcoinprivacy.net/richlist/wallets/443485/0/100

https://api.bitcoinprivacy.net/richlist/wallets/443485/summary

https://api.bitcoinprivacy.net/stats

https://api.bitcoinprivacy.net/stats/history

https://api.bitcoinprivacy.net/tx_utxos/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/0/100

https://api.bitcoinprivacy.net/tx_utxos/44c3378d8e2e9092560dd7b990c77d7d90761bace5c21f8b0c3657d697f714ea/summary

https://api.bitcoinprivacy.net/txs/443485/0/100

https://api.bitcoinprivacy.net/txs/443485/summary

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/utxos/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/0/100

https://api.bitcoinprivacy.net/wallet/3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v/summary

To write this examples was an awesome inspiration for new incoming features. We hope it could help you in someway.

Do you have questions or new ideas for awesome charts? Let us know about it in the commentaries.

Leave a Reply

Your email address will not be published. Required fields are marked *