For this project I wanted to combine several Bitcoin exchange APIs into one order book chart. An order book is a cumulative chart of bids/asks volume that slopes downward, then upward from left to right. The inspiration came from me wanting to see the overall order book, which was previously available on data.bitcoinity.org, however their order book chart stopped working for me. So I decided to make on myself. Most exchanges have an order book endpoint publicly available, and the data comes back in a similar structure. Just a little data transformation was needed to map the responses to a common format, and then I could wrangle it all into a chart.js component. I would rather have used python for this part, but Javascript is tolerable because of map/filter/reduce functions. Nodejs + Express make it extremely simple to get a back end and a front end online. I actually preferred this to my usual Django/Flask apps because there is less overhead involved in getting an asynchronous server to serve pages.

I chose to use vue-chartjs because I wanted to experiment with a compiled Javascript app, and I had enjoyable experiences with chartjs so far. A simple vue-chartjs component looks something like this:

Vue-Chartjs component with local data

import { Bar } from 'vue-chartjs'

export default {
  extends: Bar,
  data: () => ({
    chartdata: {
      labels: ['January', 'February'],
      datasets: [
        {
          label: 'Data One',
          backgroundColor: '#f87979',
          data: [40, 20]
        }
      ]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false
    }
  }),

  mounted () {
    this.renderChart(this.chartdata, this.options)
  }
}

I wanted to serve the chart page with the aggregated data local to the chart definition, but it is kind of clunky to render JSON data within a HTML template (toyed around with MustacheJS). I chose to compose my Vue app such that it has an async mounted() method that calls back to the Node server at the /data endpoint for the aggregated data to populate the chart and then render the chart. Otherwise the chart will render with no data because the API call to data is still in transit. However, doing things this way lost me flexibility with declaring options for my chart. The options I set to add axis labels and format the price to a more readable $xx,xxx format do not take effect. If I go against what the documentation says, and pass the options in directly rather than a this.options reference, the axis labels and formatters work, but the rest of the chart breaks.

I developed and tested with a local docker image using docker-compose and a .yml definition. I mounted the project folder on the container and configured Nodejs to allow for hot-reloading. That way I could rapidly develop my backend code and see my changes live. For the Vue app all I had to do was run npm run build and add the dist folder to express.static paths and viola, Nodejs/Vuejs app.

Overall the project was fun to work on, I enjoyed getting more exposure to Javascript and its ecosystem. I liked using Nodejs for an API centered project as it is easier to work with JSON data compared to my experience in Python, where I would constantly be doing .get(key, {}).get(key2, None)... However I can't help but feel I'm missing the Javascript equivalent of Pandas in this toolset. This makes me want to wrap a Vuejs app in a Python Flask backend for my next data oriented web app.