Combines Google Analytics with a company's marketing events. Utilizes JavaScript, Node.js, Express, Handlebars, jQuery, and PostgreSQL
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Journal Analytics

What is Journal Analytics?

Journal Analytics allows users to connect site activity data obtained from their Google Analytics accounts with events posted by their team. Had a booth set up at a 5K event? Post it here! Submitted a blog post on multiple platforms? Post it here! Keep a journal of all the efforts you put into your buisness on and off the web using Journal Analytics. Journal Analytics displays these events so you can visualize how they affect activity on your site.

The Team:

James Hong:

Primary team role: Chart master
Contributions: Utilized Google Analytics API, HighCharts, and ChartJS to render graphs. Assisted in creating server, routes, and API.

Katie Lane:

Primary team role: Styling wizard
Contributions: Main focus was HTML, CSS, JavaScript, UI/UX, and jQuery for entire site. Created the Journal Analytics logo, site design, and branding. Tested responsive design and implemented changes with team as needed. Ensured consistent design throughout site. Assisted in creating server, routes, and API.

Sarah Abbey:

Primary team role: Database magician
Contributions: Implemented Google OAuth using Passport.js. Assisted in creating server, routes, and API. Wrote PostgreSQL database queries to create, retrieve, update, and delete information. Created EC2 instance to host site and database. Assisted all team members in connecting to database via Postico so all members could view the same information and edit the database schema as needed. Wrote JavaScript for 'Team Management' and 'Team Events' pages.

Documented Progress

Challenges & Solutions

Some of the biggest challenges we faced with this project build included:

Challenge: Google Analytics API did not allow for server-side rendering of graphs using JavaScript.
Solution: Obtained raw data from graph after render. Used raw data with ChartJS and HighCharts libraries to render graphs and have more control over graph appearance.

Challenge: Combining server-side rendering with user interface.
Solution: Used Express and Handlebars to render different page views. Used JavaScript and jQuery to update specific page elements after page is rendered.

Stretch Goals

  • Customizability for user profiles, including types of graphs preferred and additional graphs for other analytical data sets.
  • Researching Google Analytics API in the future to see if Google creates an API utilizing server-side rendering. As for now, they only have a Beta API.
  • Creating a guide for managers of the Google Analytics account to add additional users for read only basis. This allows others to see data through Journal Analytics and add events without being granted access to the Google Analytics account.


  • JavaScript
  • Node.js
  • Express
  • Handlebars
  • Google Analytics API

JavaScript Libraries

  • JQuery
  • HighCharts
  • ChartJS
  • MomentJS
  • DDSlickJS
  • Passport.js


  • Mocha
  • Chai

Live Demo

journal analytics demo link to youtube

Code Snippets:

This code obtains a user's profile information from Google after authentication. The query updates a row if it already exists or inserts a new row if the row does not exist already.

passport.use(new GoogleStrategy({
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: process.env.GOOGLE_CALLBACK
    function(accessToken, refreshToken, profile, done) {
        var firstname =;
        firstname = firstname.replace("'", "''");
        var surname =;
        surname = surname.replace("'", "''");`
        insert into users (email, firstname, surname)
        values ('${profile.emails[0].value}', '${firstname}', '${surname}')
        on conflict (email)
        do update set (firstname, surname) = ('${firstname}', '${surname}')
        where = '${profile.emails[0].value}';
        select * from users where email = '${profile.emails[0].value}';
            .then((result) => {
                done(null, profile.emails[0].value);

This snippet shows how user events are filtered by the date the user clicks on the graph and added to the modal.

const renderEvents = (googleAnalytics, userEvents, userDateClicked) => {

  // match date requested
  let filteredEventsByDate = userEvents.filter(x => x.event_date === userDateClicked)
  // early return for no events

  // sets date at top of modal. emptys .top-modal-info span if has been appended before
  let title = $('.top-modal-info')
  let date = `Date: ${userDateClicked}`
  // if no events for day selected
  if (filteredEventsByDate.length === 0) {
    let parent = document.querySelector('.modal-list')
    let message = document.createElement('h2')
    message.textContent = 'No events for this date :(' = 'left'


Screenshot of home page

Landing page

Screenshot of login page

Login page

Screenshot of main sessions graph

Main graph showing total sessions on site. A plus icon appears if your team has added an event on this day.

Screenshot of main sessions graph on mobile

Main graph within mobile version.

Screenshot of events modal

This events modal pops up when a user clicks on the graph on a particular day. It shows the events posted for that day.

Screenshot of pie chart

Pie graph showing distribution of events your team has added by method (ex. Facebook, Twitter, etc).

Screenshot of adding events form

Users can add events for their team.

Screenshot of site traffic over the past two years

Bar chart highlighting total sessions over the past 2 years.

Screenshot of weekly network referrals

Weekly network referrals

Screenshot of 'Team Management' page

User can see all active members on their teams

Screenshot of editing events

User can edit or delete their team's events on the "Team Events" page