--- title: Assignment 4 | Additional Hypertext Features tags: assignment --- <span style="font-size: 50px;">**Assignment 4: Additional Hypertext Features**</span> :::info **Released: November 3rd** **Due: November 22nd at 11:59 PM 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 is more self guided and "choose your own path" than the others, and should lead nicely into the final project! Since this project is more more open-ended than the others, **there is no deployed demo**. We have included some screenshots to offer inspiration for how to design this functionality, but we would like to see how you can come up with designs and user experiences of your own without a reference implementation. ![](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 2000-level 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. You may ask questions to other TAs as well, but they may be less prepared to help you (and may redirect you to another TA). - Graph visualization: **Jenny, Sedong, Patrick** - Search: **Nick, Alina** - Freeform canvas: **Andrew** - Temporal media: **Becca** We've 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 For questions about a particular feature, you should target going to the specified TA(s) office hours. :::warning **Note**: There is 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 ➡️ [Assignment 3 Feedback Form](https://forms.gle/grwDu6qTyLais6f3A)** ⬅️ - [ ] Join the relevant Slack channels for the features you will be implementing - [ ] Implement the graph visualization feature - [ ] Implement your choice of optional feature(s) # **Required Feature: Graph Visualization** :::info **TAs: Jenny, Sedong, and Patrick** ::: 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 `npm install react-flow-renderer` - **Important:** Make sure to use `react-flow-renderer` and NOT `reactflow` - We are using v10 of React Flow, which is not the latest version, so you may see a deprecation warning upon first install (as well as banners on the documentation). 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 the 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 a lot of nodes; that's fine! As a rule of thumb, at least **6 nodes** in a graph should be visible. # **Additional Feature 1: Search** :::info **TAs: Alina and Nick** ::: Search is a critical feature for any platform containing lots of information. Our search feature will allow users to quickly find nodes by either the`node.title` or `node.content` fields. Fortunately, MongoDB provides text search capabilities. For this assignment, please refer to the [**MongoDB text search documentation**](https://www.mongodb.com/docs/v7.0/core/link-text-indexes/) and complete all mandatory functionality requirements. You can alternatively use the [MongoDB Atlas Search documention](https://www.mongodb.com/docs/atlas/atlas-search/), which provides more powerful search features. :::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 differences 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. 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 in the 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: Andrew** ::: 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: Becca** ::: We have spent half of the semester on implementing text nodes and image node, but at times YouTube videos or Soundcloud songs 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` or `Complete Link` button, media should automatically pause - [ ] Upon completing linking (closing the modal), media 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. :::danger Please ensure your entire project is anonymous and your name is not present anywhere (including in the deploy URLs), since we use anonymous grading. ::: # **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 Note that there are no auto-graded portions of this assignment (no points awarded for linting or formatting). Note that you could still lose points for not using the linting or formatting tools if it causes your code to be difficult to read when the TA is grading it. 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 graph visualization and **at least one additional feature**. If you are taking the course as a capstone or for graduate student credit we expect minimum functionality in graph visualization and **at least two additional features**. If you'd like, you can implement an additional feature beyond that for extra credit.