Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type annotations #41

Merged
merged 15 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- Added style and automatic layout tests for the `draw` function.
- Updated documentation, tests, and examples to reflect the `isClass` attribute being optional and set to `false` by default.
- Removed unused imports in `demo_C.js`.
- Added type interfaces and type annotations to `style.ts`.
- Added `DrawnEntity` type annotations to source code files.

## [0.1.0] - 2024-04-16

Expand Down
21 changes: 11 additions & 10 deletions memory-viz/src/automate.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { MemoryModel } from "./memory_model";
import { config } from "./config";
import { DrawnEntity } from "./types";

/**
* Draws the objects given in the path in an automated fashion.
*
* @param {object[]} objects - The list of objects that will be drawn on the canvas.
* @param {DrawnEntity[]} objects - The list of objects that will be drawn on the canvas.
* @param {Object} configuration - The configuration settings defined by the user.
* @param {number} width - User-defined width of the canvas.
* @returns {MemoryModel} - The memory model that is created according to the objects given in the path (the JSON
* file)
*/
function drawAutomated(objects, width, configuration) {
function drawAutomated(objects: DrawnEntity[], width, configuration) {
const { stack_frames, other_items } = separateObjects(objects);

// Assigning the objects with coordinates.
Expand Down Expand Up @@ -43,14 +44,14 @@ function drawAutomated(objects, width, configuration) {
* of the input such that the x and y coordinates of the stack-frames are determined automatically.
*
* @param {Object} configuration - The configuration set by the user.
* @param {Object[]} stack_frames - The list of stack-frames that will be drawn
* @param {DrawnEntity[]} stack_frames - The list of stack-frames that will be drawn
* (without the specified x and y coordinates)
* @returns {Object} - Returns the object consisting of three attributes as follows: stack-frames which will be drawn,
* the minimum required height of the canvas for drawing stack frames and required width for drawing all the stack
* frames. Notably, the last two attributes will be useful in terms of dynamically deciding the width and the height
* of the canvas.
*/
function drawAutomatedStackFrames(stack_frames, configuration) {
function drawAutomatedStackFrames(stack_frames: DrawnEntity[], configuration) {
for (const req_prop of [
"padding",
"top_margin",
Expand Down Expand Up @@ -112,7 +113,7 @@ function drawAutomatedStackFrames(stack_frames, configuration) {
* desired canvas width, this function mutates the passed list to equip each object with coordinates (corresponding to
* the top-left corner of the object's box in the canvas).
*
* @param {[object]} objs - list of objects in the format described in MemoryModel.drawAll
* @param {DrawnEntity[]} objs - list of objects in the format described in MemoryModel.drawAll
* @param {number} max_width - the desired width of the canvas
* @param {*} sort_by - the sorting criterion; must be "height" or "id", otherwise no sorting takes place.
* @param {object} config_aut - additional configuration options, such as margins, paddings, e.t.c.
Expand All @@ -122,7 +123,7 @@ function drawAutomatedStackFrames(stack_frames, configuration) {
* dynamically determined height the canvas will need to be.
*/
function drawAutomatedOtherItems(
objs,
objs: DrawnEntity[],
max_width,
sort_by,
config_aut: any = {} /* to avoid undefined error */,
Expand Down Expand Up @@ -244,11 +245,11 @@ function drawAutomatedOtherItems(
* The returned object has two attributes as 'stack_frames' and 'other_items'.
* Each of these attributes are a list of objects that were originally given by the user.
*
* @param {object[]} objects - The list of objects, including stack-frames (if any) and other items, that
* @param {DrawnEntity[]} objects - The list of objects, including stack-frames (if any) and other items, that
* will be drawn
* @returns {object} an object separating between stack-frames and the rest of the items.
*/
function separateObjects(objects) {
function separateObjects(objects: DrawnEntity[]) {
let stackFrames = [];
let otherItems = [];

Expand Down Expand Up @@ -278,10 +279,10 @@ function separateObjects(objects) {
* Return the dimensions that the passed object will have if drawn on a canvas (in the context of the MemoryModel class).
* This function can be used to determine how much space an object box will take on canvas (like a dry-run), given the
* implementations of the 'draw' methods in MemoryModel.
* @param {object} obj - an object as specified in MemoryModel.drawAll, except that coordinates are missing.
* @param {DrawnEntity} obj - an object as specified in MemoryModel.drawAll, except that coordinates are missing.
* @returns {object} the width and the height the drawn object would have.
*/
function getSize(obj) {
function getSize(obj: DrawnEntity) {
// The x and y values here are unimportant; 'obj' must simply have these properties for processing by 'drawAll'.
obj.x = obj.x || 10;
obj.y = obj.y || 10;
Expand Down
3 changes: 2 additions & 1 deletion memory-viz/src/memory_model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "./style";
import { config } from "./config";
import { DOMImplementation, XMLSerializer } from "@xmldom/xmldom";
import { DrawnEntity } from "./types";

// Dynamic import of Node fs module
let fs;
Expand Down Expand Up @@ -758,7 +759,7 @@ export class MemoryModel {
/**
* Create a MemoryModel given a list of JS objects.
*
* @param {object[]} objects - the list of objects (including stack-frames) to be drawn.
* @param {DrawnEntity[]} objects - the list of objects (including stack-frames) to be drawn.
* Each object in 'objects' must include the following structure:
* @param {number} objects[*].x - Value for x coordinate of top left corner
* @param {number} objects[*].y - Value for y coordinate of top left corner
Expand Down
57 changes: 39 additions & 18 deletions memory-viz/src/style.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import merge from "deepmerge";
import { config } from "./config";
import { DrawnEntity, AttributeStyle, Style } from "./types";

// Built-in style for drawing text on canvas (if no style is provided by the user).
const default_text_style = {
const default_text_style: AttributeStyle = {
fill: config.text_color,
"text-anchor": "middle",
"font-family": "Consolas, Courier",
"font-size": config.font_size,
};

// Default style attributes that apply universally to any type of data.
const common_style = {
const common_style: Style = {
text_id: {
fill: config.id_color,
"text-anchor": "middle",
Expand All @@ -33,7 +34,7 @@ const common_style = {
box_type: {},
};

const category_specific_styles = {
const category_specific_styles: Record<string, Style> = {
collection: {
text_value: { fill: config.id_color },
},
Expand All @@ -48,22 +49,37 @@ const category_specific_styles = {
},
};

const immutable = ["int", "str", "tuple", "None", "bool", "float", "date"];
const collections = ["list", "set", "tuple", "dict"];
const immutable: Array<string> = [
"int",
"str",
"tuple",
"None",
"bool",
"float",
"date",
];
const collections: Array<string> = ["list", "set", "tuple", "dict"];

const primitives = ["int", "str", "None", "bool", "float", "date"];
const primitives: Array<string> = [
"int",
"str",
"None",
"bool",
"float",
"date",
];

/**
* Populates a user-passed style object --to the extent needed-- with default data (to adhere to the interface of the
* style object). Needed to avoid errors of the type "TypeError: Cannot set properties of undefined (setting 'x')", as
* well as many more.
* @param {Object} object : the object that represents a Python object the user wants drawn. The style object
* @param {DrawnEntity} object : the object that represents a Python object the user wants drawn. The style object
* corresponding to 'object' will be extracted be doing object.style.
* @param {Number} seed : a numeric seed. If valued between 1 and 2^31, RoughJS will generate the exact same shape(s)
* when provided with the same seed. If valued at 0, RoughJS will generate random shape(s).
* @returns {Object}
* @returns {Style}
*/
function populateStyleObject(object, seed) {
function populateStyleObject(object: DrawnEntity, seed: Number) {
let style_so_far = common_style;

let object_type;
Expand All @@ -90,26 +106,31 @@ function populateStyleObject(object, seed) {
}

// Constants employed to establish presets for styles.
const HIGHLIGHT_TEXT = { "font-weight": "bolder", "font-size": "22px" };
const FADE_TEXT = { /*'font-weight': "normal",*/ "fill-opacity": 0.4 };
const HIDE_TEXT = { "fill-opacity": 0 };
const HIGHLIGHT_BOX_LINES = { roughness: 0.2, strokeWidth: 4 };
const HIGHLIGHT_BOX = {
const HIGHLIGHT_TEXT: AttributeStyle = {
"font-weight": "bolder",
"font-size": "22px",
};
const FADE_TEXT: AttributeStyle = {
/*'font-weight': "normal",*/ "fill-opacity": 0.4,
};
const HIDE_TEXT: AttributeStyle = { "fill-opacity": 0 };
const HIGHLIGHT_BOX_LINES: AttributeStyle = { roughness: 0.2, strokeWidth: 4 };
const HIGHLIGHT_BOX: AttributeStyle = {
roughness: 0.2,
strokeWidth: 4,
fill: "yellow",
fillStyle: "solid",
};
const FADE_BOX_LINES = { roughness: 2.0, strokeWidth: 0.5 };
const FADE_BOX = {
const FADE_BOX_LINES: AttributeStyle = { roughness: 2.0, strokeWidth: 0.5 };
const FADE_BOX: AttributeStyle = {
roughness: 2.0,
strokeWidth: 0.5,
fill: "rgb(247, 247, 247)",
fillStyle: "solid",
};
const HIDE_BOX = { fill: "white", fillStyle: "solid" };
const HIDE_BOX: AttributeStyle = { fill: "white", fillStyle: "solid" };

const presets = {
const presets: Record<string, Style> = {
highlight: {
text_value: HIGHLIGHT_TEXT,
text_id: HIGHLIGHT_TEXT,
Expand Down
26 changes: 26 additions & 0 deletions memory-viz/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export interface DrawnEntity {
name?: string;
type?: string;
x?: number;
y?: number;
id: number | string;
value: any;
show_indexes?: boolean;
style?: Style;
height?: number;
width?: number;
rowBreaker?: boolean;
}

export interface AttributeStyle {
[propName: string]: string | number;
}

export interface Style {
text_id?: AttributeStyle;
text_type?: AttributeStyle;
text_value?: AttributeStyle;
box_id?: AttributeStyle;
box_type?: AttributeStyle;
box_container?: AttributeStyle;
}
3 changes: 2 additions & 1 deletion memory-viz/src/user_functions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MemoryModel } from "./memory_model";
import { drawAutomated, getSize } from "./automate";
import { DrawnEntity } from "./types";

// Dynamic import of Node fs module
let fs;
Expand All @@ -12,7 +13,7 @@ if (typeof window === "undefined") {
*
* The format of the array of objects must adhere to the description provided in MemoryModel.drawAll.
*
* @param {string | object[]} objects - The array of objects to be drawn: this could be passed as an actual JavaScript
* @param {string | DrawnEntity[]} objects - The array of objects to be drawn: this could be passed as an actual JavaScript
* array of objects, or as a JSON file containing the object array. This array of objects may also include the
* user-defined style configuration. See the demo files and style.md file for details.
* @param {boolean} automation - Whether the coordinates (of the objects on the canvas) should be automatically
Expand Down
Loading