Skip to content

Data Visualizer

ngxingyu edited this page Jan 30, 2022 · 8 revisions

image

The data visualizer tool is a tool that allows the visualization of data in a convenient way.

draw_data is the Source function corresponding to the data visualizer.

How to use

draw_data is a varargs function; multiple data structures can be used as parameters in a single draw_data call. Each draw_data call maps to a single step, which can then be stepped through using the left and right arrow keys (when the side content panel is focused), or the "Previous" and "Next" buttons.

For example, the following will generate a single step containing two drawings, one for each list.

draw_data(list(1,2,3), list(4,5,6));

image

The following snippet shows how the different steps are shown when draw_data is called multiple times.

for_each(draw_data, build_list(i => build_list(x => x, i + 1), 3));

image

image

image

Code structure

The code for the data visualizer resides in src/features/dataVisualizer

src/features/dataVisualizer/
- drawable/ # React components corresponding to various drawings
  - Drawable.ts # exposes the Drawables to external classes
  - ArrayDrawable.tsx # draws a row of boxes representing a pair or array
  - ArrowDrawable.tsx # draws an arrow used with pairs, arrays and functions
  - FunctionDrawable.tsx # draws two balls representing a function
  - NullDrawable.tsx # draws the line corresponding to a slash, which represents a null value in a box-and-pointer diagram
- tree/
  ## Tree ##
  - Tree.tsx # Tree class responsible for parsing a Source data structure; TreeDrawer class responsible for drawing a parsed Tree
  ## Tree nodes ##
  - TreeNode.ts # exposes the TreeNodes to external classes
  - BaseTreeNode.ts # TreeNode class representing a tree node
  - DataTreeNode.tsx # A TreeNode that corresponds to a piece of data (data is defined as a non-pair and non-function)

  ## Drawable (cacheable tree nodes) ##
  - DrawableTreeNode.tsx # A TreeNode that has a pre-defined drawable, i.e. ArrayTreeNode and FunctionTreeNode. These are nodes that represent non-primitives, and can be pointed at back twice in the same structure (e.g. `pair(lst, lst)`)
  - ArrayTreeNode.tsx # TreeNode representing a pair or array
  - FunctionTreeNode.tsx # TreeNode representing a function
- Config.ts # configuration for drawings
- list.js # definitions of Source data structures and functions, in Javascript
- DataVisualizer.tsx # the main public-facing class
- DataVisualizerTypes.tsx # Typescript type definitions corresponding to Source types (pairs, lists, etc.).
- DataVisualizerUtils.tsx # utility functions

The data visualizer also makes use of:

  • src/commons/saga/WorkspaceSaga.ts
  • src/commons/util/JsSlangHelper.ts
  • src/commons/sideContent/SideContentListVisualizer.tsx

Summary

The main outfacing code is in DataVisualizer.tsx, where the static functions init, drawData, and clear are exposed. This is used by the corresponding side content React component (the one responsible for rendering the content of the draw data tool at the right side of Source Academy Playground) to render the drawings of the data.

What happens in a single "run" of the code in Source Academy is:

  1. WorkplaceSaga cleans up the environment, and calls DataVisualizer.clear to reset the data visualizer's state.
  2. Each call of draw_data in the code corresponds to a Step, which corresponds to an array of drawings, one for each structure in the varargs. The internal steps list of DataVisualizer is then appended with the new Step, and DataVisualizer.setSteps is called.
  3. At the end of all the calls, the side content React component has an array of Steps corresponding to the draw_data calls.

DataVisualizer

DataVisualizer.init

DataVisualizer.init is called by SideContentDataVisualizer to attach a listener function setSteps. setSteps will be called by DataVisualizer when the steps -- each corresponding to a draw_data call -- are updated.

DataVisualizer.draw_data

DataVisualizer.drawData is the function that corresponds to draw_data in Source Academy.

The way that draw_data invokes this is via JsSlangHelper.visualizeData, which is called by Source.

DataVisualizer.clear

DataVisualizer.clear is used to reset the list visualizer's state whenever the code is re-run, so as to clear the drawings.

Future improvements

  • Draw arrows between structures. i.e. when calling draw_data(a, pair(a, a)), just draw an instance of a, and draw arrows from the second structure.
  • Turn into a module based on the Dynamic Module system
  • Improve the scrolling behaviour for tall structures (anchor the top bar)