---
# System prepended metadata

title: Assignment 4 | Additional Hypertext Features
tags: [assignment]

---

---
title: Assignment 4 | Additional Hypertext Features
tags: assignment
---

<span style="font-size: 50px;">**Assignment 4: Additional Hypertext Features**</span>
:::info
**Released: November 2nd**
**Due: November 22nd, 11:59pm ET**
:::

<!-- INFO BOXES 
:::success GREEN
This is for any step by step instructions that students should follow. 
:::

:::info BLUE
This is for important assignment information throughout the assignment:
**Released: September 8th, 6:00pm ET** 
**Due: September 15th, 11:59pm ET** 
:::

:::warning YELLOW
Use this info box for disclaimers.
:::

:::danger 
Use this info box for important points that students should not miss!
:::

:::spoiler Dropdown list
Use this 
:::
 -->

<!-- TYPESCRIPT CODE BLOCKS  
```typescript
const list = [10, 20];
console.log(list.map(x => (x * x)))
```
-->

 
<!-- HOW TO CHANGE COLOR IN MARKDOWN
<span style="background:aliceblue">some text with a **lightblue** background</span>

<span style="color:red">some **red** text</span> 
-->

<!-- These are a list of shortcuts available. -->
*[HTML]: Hyper Text Markup Language
*[W3C]:  World Wide Web Consortium
*[NPM]: Node Package Manager
*[IDE]: Integrated Development Environment
*[MERN]: MongoDB, Express, React, NodeJS
*[Yarn]: Yet Another Resource Negotiator

# **Introduction**

This project will operate more like the final project than the others and should lead nicely into the final project!

![](https://c.tenor.com/HgjpIg9fxH0AAAAC/excited-lets-get-this-party-started.gif)

:::success
**The requirements for this assignment are as follows:** You are expected to complete the graph visualization feature and at least **one** additional feature.

**If you are taking this course as a capstone or for graduate student credit:** You should choose **two** of the additional features to implement!

:::

Because this assignment is very open-ended, each TA will support a specific feature so that they can best help you.

- Graph visualization: Amrit and Brynn
- Search: Jinoo and Nick 
- Freeform canvas: Zach
- Temporal media: Chai

For questions about a particular feature, you should go to the specified TA or TAs' office hours and direct any private questions on Slack to them.

We've also created Slack channels for each feature, where you can post public questions:
- `#graph` for questions about graph visualization
- `#search` for questions about search
- `#freeform` for questions about freeform canvas
- `#temporal` for questions about temporal media

:::warning
**Note**: No new repo to clone for this assignment! Because we are implementing code that will not interact with Assignment 3 features, you should iterate upon your Assignment 3 code base for Assignment 4. 
:::



## **Checklist**
- [ ] Complete the [Midsemester Feedback Form](https://docs.google.com/forms/d/e/1FAIpQLSf3s0yB_NuXzl6prqoXriVJyvBeb660ay7gTvuoG0BJ3L6unQ/viewform)
- [ ] Join the relevant Slack channels for the features you will be implementing
- [ ] Implement the graph visualization feature
- [ ] Implement your optional feature(s)

# **Required Feature: Graph Visualization**
:::info
**TAs: Amrit and Brynn**
:::
Thus far, our hypertext system hasn't had any visualization of links between nodes.

To visualize our nodes and links, we'll be using the [React Flow package](https://v10.reactflow.dev/docs/getting-started/core-concepts/) to build a graph by creating a list of nodes and edges.

:::info
Minimum functionality requirements:
 - [ ] A visualization button that opens up a React Flow graph for the current node
- [ ] The graph shows the current node and the nodes it has links to/from, with links represented as edges between the nodes.  
- [ ] The nodes in the graph should be arranged such that they're all visible
::: 

Example visualization
![](https://i.imgur.com/ZBYGnCj.png)
- In the example, we're currently at the Dog node, which has links to the Keeshond, Spaniel, and Pomeranian nodes

Suggested roadmap:
1. Install React Flow using `yarn add react-flow-renderer`
    - **Important:** Make sure to use `react-flow-renderer` and NOT `reactflow`
3. Review the React Flow documentation [here](https://v10.reactflow.dev/docs/getting-started/core-concepts/) to understand how to create a basic graph with nodes and edges 
4. Add a button and modal for the visualization 
5. Add the current node, its links, and the nodes it links to to a React Flow graph in the modal
6. Come up with a way to automatically position the nodes in the graph such that they’re all visible, like in the above example. 
    - A basic layout strategy may fail when there are lots of node; that's fine. As a rule of thumb, if there are 6 nodes in your graph, they should all be visible.

# **Additional Feature 1: Search** 

:::info
**TAs: Jinoo and Nick**
:::

Search is a critical feature for any platform with lots of information. 

Our search feature will allow users to quickly find nodes by either `node.title` or `node.content` fields. Fortunately, MongoDB provides text search capabilities. For this assignment, please refer to the [**MongoDB text search documentation**](https://docs.mongodb.com/drivers/node/v4.0/fundamentals/crud/read-operations/text/) and complete all mandatory functionality requirements:
:::info
**Functionality requirements:** 

- [ ] Search nodes by indexing their `node.title` and `node.content` fields
- [ ] Sort search results by relevancy score (see 'Sort by Relevance' section on [**this**](https://docs.mongodb.com/drivers/node/v4.0/fundamentals/crud/read-operations/text/) page)
- [ ] Frontend UX supports filtering of search results by node type (image, text, etc.)
- [ ] Frontend UX supports the sorting of search results by date created or last updated (most recent at the top) - pick either date created or last updated, no need to provide both options
- [ ] When clicking on a search result, the user is automatically navigated to that node
:::

:::warning
**MongoDB vs Mongoose packages:**

There are two popular packages that support MongoDB functionality for Node.js: `mongodb` and `mongoose`. For the purposes of this assignment, we will be sticking to `mongodb` which is the native package provided by MongoDB for Node.js applications. Please make sure that when reading documentation or help forums online, that it is for the `mongodb` and not the `mongoose` package. For more on the difference between these two packages you can read [this](https://stackoverflow.com/questions/28712248/difference-between-mongodb-and-mongoose) thread.

Note, while we want you to use the `mongodb` package for this assignment, you can use either package for your final project!
:::

### **Recommended steps:**
1. Write a backend endpoint in `server/src/nodes/NodeRouter.ts` that when given a string, your search term, will return a list of nodes (sorted by relevancy) that are related to that search term. Note, this will require adding to `BackendNodeGateway` and `NodeCollectionConnection` - just as we have done for all previous endpoints. Think about the best way for the client to send the desired search string to this endpoint.
2. Ensure that this backend endpoint works as expected using [Postman](https://www.postman.com/) (refer to Lab 1 or online documentation for a refresher on Postman if needed)
3. Develop and incorporate a search bar component in your frontend that will make a request to this newly created search endpoint
4. Incorporate a way to display search results
5. Develop navigation functionality such that you navigate to the relevant node upon clicking on a search result
6. Develop frontend filtering based on node type
7. Develop sorting by last updated/created functionality

:::danger
**Differences in documentation and our code:**

In the previously mentioned documentation for `mongodb` search, there are some alterations you will need to make:
- When the documentation says: `db.<collection-name>.<method-name>`, you will need to use: `this.client.db().collection(this.collectionName).<method-name>` in `NodeCollectionConnection.ts` instead.
:::

# **Additional Feature 2: Freeform Canvas**

:::info
**TA: Zach**
:::


Interested in implementing a Figma / Dash / Miro style unbounded 2D canvas? Then you should choose to do `freeform canvas`!

This will involve updating the `INode` object such that it includes the necessary metadata (`x`, `y`...) and understanding how `onPointerDown`, `onPointerMove` and `onPointerUp` can be used to pan the canvas and drag documents around on it. `onPointerMove`, `onPointerDown` and `onPointerUp` have been used before in the codebase, but understanding the logic behind it can go a long way!

<div style="text-align:left; margin-bottom: 20px"><img style="border-radius:5px; width:700px; border:solid 2px black" src="https://i.imgur.com/vCJxcgF.gif" /></div>

:::info
**Functionality requirements:** 
- [ ] Drag documents around the canvas
- [ ] Pan / scroll to navigate around the canvas 
- [ ] Ensure that all metadata is permanent and stored in the database
:::

### **Recommended steps:**
1. Implement a new `Canvas` view option for folder nodes in your codebase.
2. Create intuitive frontend components that display node information (the list and grid previews are examples). Rendering accurate node information early on can be helpful for testing.
3. Refactor `INode` and any relevant types to include a property `metadata`. Metadata by definition simply means data that describes other data; in our case, `{x, y}` could describe its node's position.
    -- Make sure to catch every case that handles node properties!
5. Add functionality in your node components to handle `metadata`. At a high level, draggable behavior depends on the different states of users' inputted mouse events. Track the cursor's location on the screen in combination with these states, and mirror the appropriate changes when moving nodes.
6. To implement panning, consider the highest parent div in your viewport and its frame relative to the screen; could some nodes be dragged "behind" the sidebar and header? Have a clear hierarchy of the canvas' layers, and where the nodes would be located. Simplify what a panning effect is actually doing, and use `PointerEvent`s in a similar way to step 4 to shift `divs` appropriately.
7. Save node `metadata` to database through `FrontendNodeGateway`. This functionality could be automatic or triggered manually.

You do not have to follow these steps! There are many ways to abstract and implement this functionality.

# **Additional Feature 3: Temporal Media**
:::info
**TA: Chai** 
:::
We have spent half of the semester on implementing text nodes and image node, but at times YouTube video or Audible audiobooks can be a great addition to your hypertext system. Choose this track to implement time-based media nodes in your system!

For this assignment, we recommend you using [React Player](https://www.npmjs.com/package/react-player) to easily support both audio and video nodes. The hard part of this track is to extract time information on the anchor we create - the anchor would ideally have a timestamp associated with it. 

![](https://i.imgur.com/308yUjL.png)

:::info
**Functionality requirements:** 
- [ ] Support both Audio/Video media nodes via media URL link
- [ ] For temporal media nodes, anchors should contain information about timestamp
- [ ] Upon clicking `Start Link` button, video should automatically stop
- [ ] Upon completing linking, video should automatically resume
- [ ] Single click of link should seek video/audio to specific timestamp
- [ ] Preserve basic linking functionality
:::


### **Recommended steps:**
1. Read documentation for React Player, and implement a new type of node to support displaying temporal media.
2. Work on adding timestamp information to temporal anchors.
3. Fine-tune the system to add autostop, timestamp seek, and auto resume functionalities.


# **Handin**

Deploy your frontend and backend as in previous assignments, and include the URLs in your README. Then submit your code on Gradescope.

# **Grading**

- 20pts of your grade will be based on meeting the functionality requirements for graph visualization
- 70pts of your grade will be based on meeting the functionality requirements for your additional feature(s)
- 10pts of your grade will be based on deployment

The TA grading will be checking each of the functionality requirements and will only mark you down if you don't meet one of the check boxes. Since each optional feature in this assignment has a different number of functionality requirements, points lost on a missing functionality requirement will be scaled to the number of functionality requirements for that specific feature.

We are expected minimum functionality based on the functionality requirements for **at least one additional feature**. If you are taking the course as a capstone or for graduate student credit we expect minimum functionality in **at least two additional features**.

If you'd like, you can implement an additional feature beyond that for extra credit.