-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert data visualizer to Typescript (#1685)
* Begin moving ListVisualizer to jsx * Convert list visualizer to tsx * Added types * clear list viz done * Finish migration of list visualizer to TS * Add documentation to list visualizer ts * Fix tsx formatting * Fix list visualizer issues - Fix visualizer not caching long data asterisk ids - Fix visualizer clear not working * Fix draw-data issues * Fix formatting * Formatting fixes * Changed setStep type * Fixed setsteps function * setSteps fixed * Initialised setSteps * Fix PR concerns * format Co-authored-by: VimuthM <vimuthmendis@gmail.com> Co-authored-by: martin-henz <henz@comp.nus.edu.sg> Co-authored-by: Vimuth <62249192+VimuthM@users.noreply.github.com>
- Loading branch information
1 parent
352a6a0
commit 5bfa5f2
Showing
22 changed files
with
1,527 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** | ||
* Represents the config used to draw the drawings. | ||
*/ | ||
export const Config = { | ||
StrokeWidth: 2, | ||
Stroke: 'white', | ||
Fill: 'white', | ||
DistanceX: 50, | ||
DistanceY: 60, | ||
|
||
BoxWidth: 90, | ||
BoxHeight: 30, | ||
VertBarPos: 0.5, | ||
BoxSpacingX: 50, | ||
BoxSpacingY: 60, | ||
|
||
CircleRadius: 12, | ||
|
||
ArrowSpace: 5, | ||
ArrowSpaceH: 13, // horizontal | ||
ArrowLength: 8, | ||
ArrowAngle: 0.5236, //25 - 0.4363,//20 - 0.3491,// 30 - 0.5236 | ||
|
||
Padding: 5, | ||
CanvasWidth: 1000 | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { Layer, Stage, Text } from 'react-konva'; | ||
|
||
import { Data, Step } from './ListVisualizerTypes'; | ||
import { findDataHeight, findDataWidth, isFunction, isPair, toText } from './ListVisualizerUtils'; | ||
import { Tree } from './tree/Tree'; | ||
import { DataTreeNode, FunctionTreeNode } from './tree/TreeNode'; | ||
|
||
/** | ||
* The list visualizer class. | ||
* Exposes three function: init, drawData, and clear. | ||
* | ||
* init is used by SideContentListVisualizer as a hook. | ||
* drawData is the draw_data function in source. | ||
* clear is used by WorkspaceSaga to reset the visualizer after every "Run" button press | ||
*/ | ||
export default class ListVisualizer { | ||
private static empty(step: Step[]) {} | ||
private static setSteps: (step: Step[]) => void = ListVisualizer.empty; | ||
private static _instance = new ListVisualizer(); | ||
|
||
private steps: Step[] = []; | ||
private nodeLabel = 0; | ||
private nodeToLabelMap: Map<DataTreeNode, number> = new Map(); | ||
|
||
private constructor() {} | ||
|
||
public static init(setSteps: (step: Step[]) => void): void { | ||
ListVisualizer.setSteps = setSteps; | ||
} | ||
|
||
public static drawData(structures: Data[]): void { | ||
if (!ListVisualizer.setSteps) { | ||
throw new Error('List visualizer not initialized'); | ||
} | ||
ListVisualizer._instance.addStep(structures); | ||
ListVisualizer.setSteps(ListVisualizer._instance.steps); | ||
} | ||
|
||
public static clear(): void { | ||
ListVisualizer._instance = new ListVisualizer(); | ||
ListVisualizer.setSteps(ListVisualizer._instance.steps); | ||
} | ||
|
||
public static displaySpecialContent(dataNode: DataTreeNode): number { | ||
return ListVisualizer._instance.displaySpecialContent(dataNode); | ||
} | ||
|
||
private displaySpecialContent(dataNode: DataTreeNode): number { | ||
if (this.nodeToLabelMap.has(dataNode)) { | ||
return this.nodeToLabelMap.get(dataNode) ?? 0; | ||
} else { | ||
// if (typeof display === 'function') { | ||
// display('*' + nodeLabel + ': ' + value); | ||
// } else { | ||
console.log('*' + this.nodeLabel + ': ' + dataNode.data); | ||
this.nodeToLabelMap.set(dataNode, this.nodeLabel); | ||
// } | ||
return this.nodeLabel++; | ||
} | ||
} | ||
|
||
private addStep(structures: Data[]) { | ||
const step = structures.map(this.createDrawing); | ||
this.steps.push(step); | ||
} | ||
|
||
/** | ||
* For student use. Draws a list by converting it into a tree object, attempts to draw on the canvas, | ||
* Then shift it to the left end. | ||
*/ | ||
private createDrawing(xs: Data): JSX.Element { | ||
/** | ||
* Create konva stage according to calculated width and height of drawing. | ||
* Theoretically, as each box is 90px wide and successive boxes overlap by half, | ||
* the width of the drawing should be roughly (width * 45), with a similar calculation | ||
* for height. | ||
* In practice, likely due to browser auto-scaling, for large drawings this results in | ||
* some of the drawing being cut off. Hence the width and height formulas used are approximations. | ||
*/ | ||
let layer: JSX.Element; | ||
|
||
if (isPair(xs)) { | ||
layer = Tree.fromSourceTree(xs).draw(500, 50); | ||
} else if (isFunction(xs)) { | ||
layer = <Layer>{new FunctionTreeNode(0).createDrawable(50, 50, 50, 50)}</Layer>; | ||
} else { | ||
layer = ( | ||
<Layer> | ||
<Text | ||
text={toText(xs, true)} | ||
align={'center'} | ||
fontStyle={'normal'} | ||
fontSize={20} | ||
fill={'white'} | ||
/> | ||
</Layer> | ||
); | ||
} | ||
const stage = ( | ||
<Stage key={xs} width={findDataWidth(xs) * 60 + 60} height={findDataHeight(xs) * 60 + 100}> | ||
{layer} | ||
</Stage> | ||
); | ||
return stage; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Source-related types | ||
export type Data = any; | ||
export type Pair = [Data, Data]; | ||
export type EmptyList = null; | ||
export type List = [Data, List] | EmptyList; | ||
|
||
// Drawing-related types | ||
export type Drawing = JSX.Element; | ||
export type Step = Drawing[]; |
Oops, something went wrong.