Visualizing time series data in Vue.js
Demonstrates the use of Vue.js, vue-chartjs and Chart.js to plot the simple moving average data I am pulling from AWS AppSync.
This is the fifth of a series of posts describing my experimentation with Vue.js, AWS AppSync, Lambda and other technologies. A public GitHub repository exists with this experiment so others can learn from my efforts. For this post, I will be describing the code that resides on the
v3 tag, so feel free to checkout to this point in time:
git checkout v3. Links to the other posts in this series can be found in the first post.
In the first three posts for this Invest Guru endeavor, I built up a simple GraphQL API that uses AWS AppSync to host a GraphQL API and AWS Lambda and the Python 3.7 runtime to implement a simple resolver for handling a simple moving average query. I use the excellent Alpha Vantage API to source the simple moving average data for a specific company. I have demonstrated that the GraphQL query works by exercising it from Prisma’s GraphQL Playground.
In the fourth post, I started working on the front-end, building out a Vue.js web application that will consume the GraphQL API and present the data to the user in various presentations. I will continue to build out this Vue.js-based web application in this post. I’ll be enlisting the help of Chart.js and vue-chartjs to help me plot the simple moving average data that we are consuming from the back-end. So let’s get to it!
Add chart.js and vue-chartjs dependencies
I’ll be using Chart.js and vue.chartjs to plot datasets in the browser. Chart.js is a simple charting library that uses the Canvas API in HTML5. Chart.js has good animation support and is fairly easy to get up and running with. I will also be using vue-chartjs to facilitate the hassle-free integration of Chart.js into Vue.js. The vue-chartjs library abstracts the basic functionality of Chart.js so you can get up and running quickly, but also exposes the Chart.js object to give you maximal flexibility as you grow into more advanced uses of Chart.js. Execute the following to add the two dependencies to the Vue.js project:
yarn add chart.js vue-chartjs
Now to create our first chart component, the SimpleMovingAverageChart. I created this component in the
You will notice that I am not using a Single File Component here for the Vue.js component. The integration between Vue.js and Chart.js is much more low-level. The DOM template that would typically be included in a Single File Component cannot be used with these Vue.js/Chart.js components. The vue-chartjs documentation talks a little bit about this here. I just avoided Single File Components here so that I would not be lulled into trying to use a template with one of these types of components.
The vue-chartjs integration provides a base chart,
Line, that I am extending. The
renderChart function is provided by the
Line chart component. It accepts two
object parameters, which are detailed in the Chart.js documentation. The first parameter is the chart datasets, and the second parameter is the general options for the chart. I’m also using the
reactiveProp mixin to provide live updating of the chart when the dataset changes. This is something that the vue-chartjs integration provides and is documented here.
Next up is our chart container component, the SimpleMovingAverageChartContainer. I created this component in the
The chart container is a bit more involved — it has the responsibility of querying AWS AppSync for the simple moving average analytic data and transforming that data into datasets that Chart.js will render. Let’s run through this source code listing and highlight some of the interesting things happening here.
<template> section of the Single File Component, I am rendering the chart if, and only if, the data has been loaded. Otherwise I’ll render a loading message. I should probably also render errors up there, but I’ll save that for another day.
Dropping down into the
<script> section, I have a single required
prop (lines 22–27) that I expose for obtaining the company symbol that I will use to make the GraphQL query.
data object (lines 28–35) contains data for managing the chart container and the chart datasets. You can see the
options properties here will be used as prop values for the chart itself. The
chartData property is interesting here, as it is initially set to
null and will be generated once Apollo Client/AppSync Client return the results of the GraphQL query.
methods object, I have a single method,
buildChartDataSets, that I am using in the Apollo
result callback to transform the GraphQL response into something that Chart.js can render. I’m taking the last 30 observations of the 50 day and 300 day simple moving average observations lists and determining that they match the date of the observation (there is a chance that a 50 day observation does not have a matching 300 day observation). If they match, I add the observations to the appropriate dataset array and add the date of the observation to the
labels array. Lines 64–88 is creating a Chart.js
chartData object that contains the datasets, label, and rendering options for the line charts. The rendering options for the Line chart can be found here in the Chart.js documentation.
Lines 91–110 are the Apollo Client/AppSync Client
apollo object. This object effectively wires up the GraphQL query,
simpleMovingAverageAnalyticQuery, to this container component. We are binding the
symbol property value from the container component to the
variables object for Apollo (lines 94–98). I’m setting the
fetch-policy here to
cache-and-network, which you can read more about fetch policies here. Apollo Client will check the cache first to determine if the result of the query is cached and will only go across the network when the cache does not contain a result for that particular query (including variables).
I have an
The Home view component changes to the following:
Most of this is self-explanatory. The
symbol property in the
data object hard-codes a value. This will change in subsequent posts, but it works for our straw man implementation for now. The
apollo object that was here in the fourth post has migrated to the
SimpleMovingAverageChartContainer component that we previous saw.
The resultant line chart for the 50-day and 300-day simple moving averages analytic for Microsoft (MSFT) is below:
This concludes our straw man implementation of a serverless GraphQL back-end using AWS AppSync and Lambda and a front-end using Vue.js. I will continue to add new features and posts, so I hope that you continue to follow on with my journey. I have added a GitHub Project to this repository to collect potential features that I will be building out to evolve Invest Guru into something that is usable.