Bubble Map Demo

Blowing Conceptual Bubbles with D3 and React

This project involves two pieces:

  1. A ‘Bubble Map Viewer‘.  Viewing a bubble map (Demo here).
  2. A ‘Bubble Map Creator‘.  A tree-structure editor for creating maps (Demo here).

Backstory

My coding accomplice Shad found a demo of a d3’s ‘Zoomable Circle Packing’ feature while brainstorming ways to create visual concept maps (a shared interest).  The demo was simple, elegant and visually striking, and we were curious to see if that format might be a good way to visualize conceptual information. And so this project was born as a way to prototype ‘concept bubble maps’ to see how well they could communicate conceptual information.

Development Process

Like most web-apps, this one has two parts: the frontend and the backend.

Frontend

The frontend is handling most of the work of this project.  

The ‘Bubble Map’ page, draws heavily from the D3 demo.  The demo was modified to include an additional ‘Description’ attribute to the bubbles in the map.  This attribute is used to populate a popup box that is meant to display more in-depth information about the node.  This part is critical for our use since we are hoping to convey a lot of information about concepts using the map.  Also was updated to change the way it displays and zooms so that it only will display the current node and the children nodes.

For the ‘Bubble Map Creator’ page, the whole form is built using the React library (which is kick-ass at managing HTML and dynamic data).  React allows the bubble map data to be decoupled from the form’s HTML.  I was able to set up React classes that allow me to just feed the complete bubble map data structure (JSON encoded from the backend) to the top-level class and it will render the whole form.  Then, when the form is used to make a change (ex: use ‘Add Child’ to add a child node) it updates the data structure which triggers React to re-rendering the form with the new data to reflect the change.  If you have ever dealt with the quagmire of directly updating HTML  via JavaScript to make a dynamic form (as I have multiple times…) then this is like a dream.

The form interacts with the backend entirely via a REST API.  This means creating, loading and saving of the maps are done via ajax calls.  Doing things this was (as opposed to a traditional form submit) means that you do not have to reload the page while working.  I have grown to prefer using this approach whenever possible as it makes for a more seemless user experience and leaves open the option for ‘auto-saving’ in the background while working.  Also, since the REST API library I built takes care of the details, it means I don’t have to spend time writing code in the backend to handle processing the form requests.

Backend

This project was very frontend heavy and there was very little code I needed to write for the backend.  Basically, the backend is just responsible for storing and retrieving the bubble map data, generating the HTML for the pages, and performing CRUD operations over the REST API.  I used the Symfony2 framework and my homebrew ORM and REST API libraries which took care of a lot of the details of handling requests and interacting with the database.  The HTML pages are pretty minimal, they just loads up a blank page then JavaScript does the rest.  And there was no need to process forms etc. since that was all being done in JavaScript and the REST API.

I chose to store bubble tree data in a MySQL table:

diagram-2

  1. BubbleMapId: A unique ID for each bubble map
  2. Code: A machine-friendly name for each map (‘ArgumentationChapter1’)
  3. Name: A human-friendly name for the map (‘Argumentation: Chapter #1’)
  4. Content: Entire bubble map definition in JSON format
  5. DateTimeStamp: The last-modified timestamp for the map

Storing the whole bubble map definition in JSON severely limits the ways I can use it in the back-end.  For instance, I cannot not query the database to get an individual node of a bubble map and update it’s content.  Instead I’d have to first retrieve the entire map from the ‘Content’ field, decode it, traverse the results, update the node, then re-encode it to JSON and then update the ‘Content’ field.  

Given this, why not create a more detailed structure in the database that would make the data easier to access in the back-end?

  1. I did not foresee much need to manipulate the bubble map data on the backend. This is a prototyping project and at this point only the front-end is really the only one using the data.
  2. I’d have to create separate tables and fields that map the structure of the bubble map onto the database.  
  3. I’d have to write code that maps the JSON data received from the front-end to the DB.
  4. I’d have to update the DB structure every time the bubble map structure changes.  For instance, if at some point I decided to add a ‘color’ attribute to the bubbles, I’d not only have to update the front-end, but also update the table structure and code for storage/retrieval.

No need for a detailed back-end representation of the data plus the time it would take to build and maintain made this an easy call.  In future, if we ever decided we wanted to do some serious work in the back-end on the data, I could always migrate to a more detailed structure.

It occurred to me after building the backend that this could have been a good opportunity to try using mongoDB, since I’ve heard that there is less need to manually maintain the data structure, but I have not used mongoDB yet and did not want to tackle that as part of this project.

Future improvements:

  1. Add ‘on-hover’ events (view inner nodes, display summary as tooltip
  2. Better integration of the ‘in-depth’ dialog view
  3. Resizing window = resizing map.
  4. Sidebar map of structure.
  5. Add permissions
  6. Better interface for loading your maps (right now you need to remember name)
  7. Better way of presenting the ‘in-depth’ information (right now the pop-up box is cumbersome and generally a not-so-great solution)

Resources / Notes:

  1. The project’s GitHub page
  2. The D3 demo that inspired the project
  3. This web app builds upon:
    1. The Symfony2 framework
    2. The D3 library
    3. The React library
    4. My Homebrew ORM library
    5. My REST API library
  4. The demo map uses chapter 1 from the Great Courses’ Argumentation

 

Leave a Reply

Your email address will not be published. Required fields are marked *