Stop drowning in unnecessary meetings. Work on only what matters. Get Started.

Create a Real-time Data Analysis Platform in Nuxtjs

Create a Real-time Data Analysis Platform in Nuxtjs

Create a real-time data analytics platform with Appwrite and Nuxtjs

Creating a real-time data analytics platform can be challenging, but it can be made much easier with the right tools. One such tool is Appwrite, a modern and powerful backend-as-a-service (BaaS) platform for easily building and deploying web and mobile applications. Another helpful tool is Nuxt.js, a progressive framework for building server-rendered Vue.js applications.

This article covers creating a real-time data analytics platform using Appwrite and Nuxt.js by simulating a simple eCommerce dashboard.

Repository

Here's a link to the repo:

https://github.com/folucode/data-visualization-appwrite

Prerequisites

  • Basic understanding of CSS, JavaScript, and Nuxt.js
  • Docker Desktop installed on your computer (run the docker -v command to verify the installation); if not, install it from here
  • An Appwrite instance running on your computer. Check out this post to create a local Appwrite instance. It can also be installed using digital ocean or gitpod

Setting up the project

Create a new Nuxt.js project using the following command:

npx create-nuxt-app data-analytics-platform

This will guide you through several prompts to set up the project, including selecting a package manager, a UI framework, and additional features. Make sure to choose Axios as the HTTP client, as you'll use it to make API calls to Appwrite later.

Once you finish setting up the project, you can navigate to the project directory and start the development server using the following commands:

cd data-analytics-platform
npm run dev

Setting up an Appwrite database

To set up an Appwrite storage bucket, login to the Appwrite console and create a new project. Next, click on the Databases tab and Create database. You can give it the name ecommerce`.

Click on the ecommerce database and create a new collection in the database; call it orders. Collections serve as database tables in Appwrite.

Next, click on the collection and then add new attributes. Attributes serve as database columns in Appwrite.

The attributes you will add are:

  • customer of type string
  • price of type double

Click on the settings tab, scroll down to permissions, and add the Users role with all permissions for the orders collection.

Setting up the UI

In the components folder, create a file called DataCard.vue and paste the code below into it:

<template>
  <div class="chart">
    <div class="chart-inner stat-1">
      <div class="header">
        <div class="tagline">{{ tagline }}</div>
        <div class="count">{{ count }}</div>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    props: {
      tagline: String,
      count: Number,
    },
    name: "DataCard",
  };
</script>

This component is a simple card that will display the order details. There are two attributes: tagline and count.

Next, in the index.vue file, paste the code below:

<template>
  <div>
    <div class="container-fluid">
      <DataCard tagline="Total Customers" :count="totalCustomers" />
      <DataCard tagline="Total Orders" :count="totalOrders" />
      <DataCard tagline="Total Revenue" :count="Math.round(totalRevenue)" />
    </div>

    <button class="button" @click.prevent="makeOrder()">Create Order</button>

    <h2>Orders</h2>
    <table>
      <tr>
        <th>Order ID</th>
        <th>Customer</th>
        <th>Price</th>
      </tr>
      <tr v-for="order in orders" :key="order.$id">
        <td>{{ order.$id }}</td>
        <td>{{ order.customer }}</td>
        <td>{{ order.price }}</td>
      </tr>
    </table>
  </div>
</template>

<script>
  export default {
    name: "IndexPage",
    data() {
      return {
        orders: [],
        totalCustomers: 0,
        totalOrders: 0,
        totalRevenue: 0,
      };
    },
    methods: {},
    mounted() {},
  };
</script>

<style>
  body {
    background-color: #252830;
    color: white;
  }
  .container-fluid {
    margin-left: 18%;
  }
  .chart {
    text-align: left;
    display: inline-block;
    width: 300px;
  }
  .chart-inner {
    background-color: rgba(233, 164, 164, 0.5);
  }
  .header {
    box-sizing: border-box;
    padding: 30px 15px;
    position: relative;
    text-shadow: 1px 1px 2px black;
  }
  .tagline {
    opacity: 0.75;
    text-transform: uppercase;
  }
  .count {
    display: inline-block;
    font-size: 32px;
    font-weight: 300;
    vertical-align: middle;
  }
  table {
    font-family: arial, sans-serif;
    border-collapse: collapse;
    width: 100%;
  }
  td,
  th {
    border: 1px solid #dddddd;
    text-align: left;
    padding: 8px;
  }
  .button {
    background-color: #4caf50; /* Green */
    border: none;
    color: white;
    padding: 15px 32px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
  }
</style>

In this file, there is a DataCard to show Total Customers, Total Revenue, and Total Orders. You have a button to create an order, and this helps to save the time of building an order system since you're primarily interested in the real-time feature. The button has a click event with a function, makeOrder(), that you'll create later.

There's also a table to list all the orders in the Appwrite database.

Building the App

Before you continue, install these two packages: the Appwrite official package and faker.js, a library to generate mock data.

npm i appwrite @faker-js/faker

Connecting to Appwrite

In the pages/index.vue file, import the Appwrite package and the faker.js package, and then create an Appwrite connection like so:

...
<script>
  import { Client, Account, Databases } from "appwrite";
  import { faker } from "@faker-js/faker";

  const client = new Client();

  client
    .setEndpoint("http://localhost/v1") // The Appwrite Endpoint
    .setProject("[YOUR-PROJECT-ID]");

  const account = new Account(client);
  const database = new Databases(client);

  account.createAnonymousSession().then(
    (response) => {
      console.log(response);
    },
    (error) => {
      console.log(error);
    }
  );

  export default {
    name: "IndexPage",
    data() {
      return {
        orders: [],
        totalCustomers: 0,
        totalOrders: 0,
        totalRevenue: 0,
      };
    },
    methods: {},
    mounted() {},
  };
</script>
...

In this file, you create an Appwrite instance along with an account and database, which you'll use later in the app. Also, set up an anonymous sessiont — this saves us the time of making a whole authentication system.

In the mounted method, check whether the anonymous account is active and subscribe to the documents channel. Subscribing to a channel updates your app in real time once a change is made in the database.

... mounted() { if (account.get !== null) { try { client.subscribe("documents",
(response) => { }); } catch (error) { console.log(error, "error"); } } } ...

Making an order

Add a new method to the methods object called makeOrder. In this new method, you'll create a new order in the Appwrite database using faker.js, like so:

async makeOrder() {
  await database.createDocument(
    "[YOUR-DATABASE-ID]",
    "[YOUR-COLLECTION-ID]",
    "unique()",
    {
      customer: faker.name.fullName(),
      price: faker.finance.amount(),
    }
  );
},

Analyzing the data

To analyze the data, create a function called visualizeData and add the code below:

async visualizeData() {
  const orderDetails = await database.listDocuments(
    "[YOUR-DATABASE-ID]",
    "[YOUR-COLLECTION-ID]"
  );

  this.orders = orderDetails.documents;
  this.totalCustomers = orderDetails.total;
  this.totalOrders = orderDetails.total;

  this.totalRevenue = orderDetails.documents.reduce(
    (accumulator, currentValue) => accumulator + currentValue.price,
    0
  );
},

In this code, you first fetch the orders from the database. The reduce function accumulates the prices to obtain the total revenue.

Every time the page reloads or changes occur in the database, you want to fetch all the podcasts in real-time. To do so, call the visualizeData function in the mounted method like so:


mounted() {
  this.visualizeData();

  if (account.get !== null) {
    try {
      client.subscribe("documents", (response) => {
        this.visualizeData();
      });
    } catch (error) {
      console.log(error, "error");
    }
  }
},

The app should look like so:

Conclusion

In conclusion, building a real-time data analytics platform with Appwrite and Nuxt.js can provide a powerful and flexible data analysis and visualization solution. By leveraging the real-time capabilities of Appwrite and the versatility of Nuxt.js, you can create dynamic and interactive dashboards that allow your users to quickly understand and explore their data in real-time.

Whether you are building a platform for business analytics, IoT data analysis, or any other real-time data application, Appwrite, and Nuxt.js can provide the tools and framework you need to succeed.

Resources


About the author

Technical Author and JavaScript Developer

Related Blogs

Understanding The Anatomy Of A URL: A Breakdown of The Components And Their Significance
CESS

CESS

Mon Sep 25 2023

Understanding The Anatomy Of A URL: A Breakdown of The Components And Their Significance

Read Blog

icon
Libraries vs. Frameworks: Which is right for your next web project?
CESS

CESS

Mon Aug 21 2023

Libraries vs. Frameworks: Which is right for your next web project?

Read Blog

icon
Why you Should Use GraphQL APIs in your Next Project
Amarachi Iheanacho

Amarachi Iheanacho

Fri Feb 10 2023

Why you Should Use GraphQL APIs in your Next Project

Read Blog

icon
image
image
icon

Join Our Technical Writing Community

Do you have an interest in technical writing?

image
image
icon

Have any feedback or questions?

We’d love to hear from you.

Building a great product is tough enough, let's handle your content.

Building a great product is tough enough, let's handle your content.

Create 5x faster, engage your audience, & never struggle with the blank page.