Edit in JSFiddle

/*
demo using Bouquet analytics API with D3.js to display data distribution by states and with drill-down support.
*/

var bouquetServer = "//demo.openbouquet.io/release/v4.2";

// login with APiKey and execute function
function login(tokenUrl, updateFunc) {
    accessToken = Cookies.get("sq-token");
    if (accessToken === undefined) {
      requestToken(tokenUrl, updateFunc);
    } else {
      checkToken(accessToken, tokenUrl, updateFunc);
    }
  };

// check if a OAtuh2 token is still valid
function checkToken(accessToken, tokenUrl, updateFunc) {
    // perform /token request
    $.ajax({
      type: "GET",
      dataType: "json",
      url: bouquetServer+"/rs/tokeninfo?access_token=" + accessToken,
    }).done(function(response) {
      accessToken = response.access_token;
      updateFunc(accessToken);
    }).fail(function(response) {
      requestToken(tokenUrl, updateFunc);
    });
  };

// request a new OAuth2 token
function requestToken(tokenUrl, updateFunc) {
    // perform /token request
    $.ajax({
      type: "GET",
      dataType: "json",
      url: tokenUrl,
    }).done(function(response) {
      // auth done, get the user
      accessToken = response.access_token;
      expirationDateMillis = response.expirationDateMillis;
      Cookies.set("sq-token", accessToken, {
        expires: new Date(expirationDateMillis)
      });
      updateFunc(accessToken);
    }).fail(function(response) {
      alert("Failed to get auth token");
    });
  };
  
function format(f) {
	if (f===undefined) return null;
  if (!f.startsWith("%")) return null;
  f = f.substring(1);
  return d3.format(f);
}

// display data as a simple html table using D3
function displayTable(data) {
    // column definitions: use the reply header
    var columns = [];
    data.header.columns.forEach(function(column) {
    	columns.push({
      	head: column.name,// this is the name of the column
        cl: (column.format===undefined)?"center":"num",// value format to use if defined
        html: (column.format===undefined)?ƒ(column.pos):ƒ(column.pos,format(column.format))
        });// pos gives the value index in the result array when the format is data=TABLE
    });
    // reply info
    var tableInfo = d3.select("#tableInfo");
    var pageSize = data.info.pageSize;
    var totalSize = data.info.totalSize;
    if (pageSize > 0) {
      if (pageSize == totalSize) {
        tableInfo.select('#tableText').text("Showing "+pageSize + " Events");
      } else {
        tableInfo.select('#tableText').text("Showing "+pageSize + " Events out of " + totalSize);
      }
    } else {
      tableInfo.select('#tableText').text("No Event to show");
    }
    // populate the table
    var tableDetails = d3.select('#tableDetails');
    tableDetails.selectAll("*").remove();
    // create table
    var table = tableDetails.append('table').attr("class", "data");
    // create table header
  table.append('thead').append('tr').selectAll('th').data(columns)
      .enter().append('th').attr('class', ƒ('cl')).text(ƒ('head'));
    // create table body
    table
      .append('tbody')
      .selectAll('tr')
      .data(data.data)
      .enter()
      .append('tr')
      .selectAll('td')
      .data(
        function(row, i) {
          return columns
            .map(function(c) {
              // compute cell values for this specific row
              var cell = {};
              d3
                .keys(c)
                .forEach(
                  function(k) {
                    cell[k] = typeof c[k] == 'function' ? c[k]
                      (row, i) : c[k];
                  });
              return cell;
            });
        }).enter().append('td').html(ƒ('html')).attr('class',
        ƒ('cl'));
}

// run query
function update(accessToken) {
  $("#status").text("connected");
	var apiUrl = bouquetServer+ "/analytics/@'5899bc6715abcc6bed69d766'.@bookmark:'58a5dc6b45d778b2bdb231c9'/query?";
  apiUrl += "envelope=RESULT&data=TABLE";// get the header as well and format data as array of values
  apiUrl += "&access_token="+accessToken;// adding the OAuth token
  $('#apiUrl').text('requesting data').append($('<i class="fa fa-refresh fa-spin fa-fw"></i>'));
      // clear table and diplay spin
      var tableDetails = d3.select('#tableDetails');
      tableDetails.selectAll("*").remove();
      tableDetails.append("i").attr("class", "fa fa-refresh fa-spin fa-fw");
  $.getJSON(apiUrl, function (data) {
  		$('#apiUrl').text('').append($('<a href="'+apiUrl+'&style=HTML" target="_blank">View data in Bouquet API explorer&nbsp;<i class="fa fa-external-link"></i></a>'));
  		displayTable(data);
  }).fail(function(response) {
      $('#apiUrl').text('request failed: '+response.responseJSON.error+"("+response.responseJSON.code+")")
  });
}

// login and update
$(function() {
    var clientId = "api-key-client";
    // login with API Key
    login(bouquetServer+"/rs/token?assertion=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJhcGkta2V5LWNsaWVudCIsInN1YiI6IjU4YWM1Y2FiMTVhYmNjMTJiYjUwYTU0MCIsInVzZXJFbWFpbCI6ImRlbW9AbG9jYWxob3N0LmNvbSIsImN1c3RvbWVySWQiOiI1OGFjNTNjMDE1YWJjYzEyYmI1MGE0NWIiLCJqdGkiOiJnTmF3dHdiZzRaYXRtQ1JXVVRQYnFnIiwiZXhwIjo0NjQxNTM0NTE5LCJpYXQiOjE0ODc5MzQ1MTksIm5iZiI6MTQ4NzkzNDM5OX0.g5f1DHxESj9PvC5meP8UKXmcZzbGZIiW-qwZ7mNAZWTlMlaAdIn1EBOZzB9oAwHzQxS0qez0iRDac874YCmnHrwYI8kgVoJQvbbJedKIJjfP_V_ZPvMiAfsX0wqeCmqG4_uXZoAh_sumvyDkKGfzutAfpR3DCVkWTqfYZ-iornkyYwH89Yqe_yBNQPO4pXpf3Dg68BlruZqc-tiow3ytynyxuEYEOPYIuyRL-fLpjNstRGa_gXIQYBx9v1yVGlZsQFVviJ5PMbCgIduM36g5leA_IXprw46KxjH_snbnEvAHypZCwhNaJJxlLGBEWTMnFKqytR68CGURskRM2D0VPQ&client_id="+clientId, update);
  });
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="//openbouquet.io/js/uStates.js"></script>
<!-- creates uStates. -->
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//rawgit.com/gka/d3-jetpack/master/d3-jetpack.js"></script>
<script src="//openbouquet.io/js/js.cookie.js"></script>

<script src="https://use.fontawesome.com/1ea8d4d975.js"></script>

<h1>
<a href="https://openbouquet.io/bouquet-demo-ob" target="_parent">Bouquet API</a> simple Table demo using D3.js
</h1>

<div id="status">Connecting <i class="fa fa-refresh fa-spin fa-fw"></i></div>
<div id="apiUrl">&nbsp;</div>
<hr>

<div id="tableInfo">
  <p id="tableText">&nbsp;</p>
</div>
<div id="tableDetails" style="max-height:400px;overflow:scroll;">
</div>
body {
  margin:5px;
}

* {
  font-family: "Helvetica Neue", Helvetica,Arial,sans-serif; 
  color: #666; 
  }
  
table.data {
  border-collapse: collapse;width: 100%;
}

th, td {
  text-align: left;padding: 8px; vertical-align: top;
}

.data tr:nth-child(even) {
  background-color: #f2f2f2
}

.data th {
  background-color: #ee7914;color: white;
}

.state {
  fill: none;
  stroke: #a9a9a9;
  stroke-width: 1;
}

.state:hover {
  fill-opacity: 0.5;
}

th {
  text-align: left;
}

th,
td {
  padding: 0 1em 0.5ex 0;
}

th.center,
td.center {
  text-align: center;
}

th.num,
td.num {
  text-align: right;
}

External resources loaded into this fiddle: