Skip to content

Commit

Permalink
refactor: render graph (#71)
Browse files Browse the repository at this point in the history
[Preview Link](https://regex-vis-git-refactor-graph-bowen.vercel.app/)

~~This is a big change, so I decided to put it on hold for now.~~
- Refactor the regex graph rendering process to measure node sizes before rendering
- Use monospace fonts for the regex text
- Replace SVG `text` elements with `foreginObject`
- Refactor the `visit`, `visitNodes`, `getNodeById`, `getNodesByIds` functions, and add `lrd` function to traversal ast by post-order. Add unit tests for the above functions.
  • Loading branch information
Bowen7 authored May 13, 2023
1 parent 92b4e86 commit f77dbad
Show file tree
Hide file tree
Showing 39 changed files with 1,461 additions and 981 deletions.
5 changes: 3 additions & 2 deletions .jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module.exports = {
verbose: true,
testEnvironment: "jsdom",
moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
setupFilesAfterEnv: ["./tests/setupTests.ts"],
setupFilesAfterEnv: ["./tests/setupTests.ts", "jest-canvas-mock"],
transform: {
"^.+\\.[jt]sx?$": ["babel-jest", { configFile: "./tests/.babelrc.js" }],
},
Expand All @@ -11,7 +11,8 @@ module.exports = {
"^.+\\.svg$": "<rootDir>/tests/__mocks__/svgrMock.js",
"@/(.*)$": "<rootDir>/src/$1",
"tests/(.*)$": "<rootDir>/tests/$1",
"@vercel/analytics/dist/react": "identity-obj-proxy",
"@vercel/analytics/dist/react": "<rootDir>/tests/__mocks__/analytics.js",
"^.+\\.(css|less)$": "<rootDir>/tests/__mocks__/css.js",
},
transformIgnorePatterns: ["node_modules/(?!(.*hex-rgb))"],
}
4 changes: 4 additions & 0 deletions config-overrides.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ const {
addWebpackAlias,
addBabelPlugin,
fixBabelImports,
// addWebpackPlugin,
} = require("customize-cra")
// const BundleAnalyzerPlugin =
// require("webpack-bundle-analyzer").BundleAnalyzerPlugin
const path = require("path")

const findWebpackPlugin = (plugins, pluginName) =>
Expand All @@ -29,6 +32,7 @@ module.exports = override(
fixBabelImports("@geist-ui/react", {
libraryDirectory: "esm",
}),
// addWebpackPlugin(new BundleAnalyzerPlugin()),
overrideProcessEnv({
SENTRY_DSN: JSON.stringify(process.env.SENTRY_DSN),
VERCEL_ANALYTICS_ID: JSON.stringify(process.env.VERCEL_ANALYTICS_ID),
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@
"babel-plugin-import": "^1.13.3",
"customize-cra": "^1.0.0",
"jest": "^26.6.0",
"jest-canvas-mock": "^2.5.0",
"react-app-rewired": "^2.1.6",
"regenerator-runtime": "^0.13.9",
"ts-jest": "^26.5.6",
"ts-node": "^10.0.0"
"ts-node": "^10.0.0",
"webpack-bundle-analyzer": "^4.8.0"
}
}
95 changes: 93 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<!-- <div style="font-family: icon-font;">&#xe902;</div> -->
<div id="root"></div>
<div id="portal"></div>
<!--
Expand Down
6 changes: 4 additions & 2 deletions src/atom/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { atom } from "jotai"
import { atomWithImmer } from "jotai/immer"
import { useToasts } from "@geist-ui/core"
import { AST } from "@/parser"
import { NodeSize } from "@/modules/graph/measure"
export const undoStack: AST.Regex[] = []
export const redoStack: AST.Regex[] = []
export const nodesBoxMap: Map<
Expand All @@ -22,6 +23,7 @@ export const selectedIdsAtom = atom<string[]>([])
export const groupNamesAtom = atom<string[]>([])
export const editorCollapsedAtom = atom<boolean>(false)

export const recordLayoutEnableAtom = atom<boolean>(true)
export const selectEnableAtom = atom<boolean>(true)
export const toastsAtom = atom<ReturnType<typeof useToasts> | null>(null)

export const sizeMapAtom = atom<Map<AST.Node | AST.Node[], NodeSize>>(new Map())
export const isPrimaryGraphAtom = atom<boolean>(true)
2 changes: 1 addition & 1 deletion src/components/header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const Header = memo(({ onThemeChange, theme }: Props) => {
<Link to="/">
<div className="logo">
<LogoSvg />
<span>Regex-Vis</span>
<span>Regex Vis</span>
</div>
</Link>
<div className="nav">
Expand Down
2 changes: 2 additions & 0 deletions src/components/input/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from "react"
import { Input as GeistInput, useTheme } from "@geist-ui/core"
import { useDebounceInput } from "@/utils/hooks"
import { REGEX_FONT_FAMILY } from "@/constants"

type Props = Omit<React.ComponentProps<typeof GeistInput>, "onChange"> & {
validation?: RegExp
Expand Down Expand Up @@ -44,6 +45,7 @@ const Input: React.FC<Props> = (props) => {
onKeyDown={handleKeyDown}
{...restProps}
{...debouncedBindings}
style={{ fontFamily: REGEX_FONT_FAMILY }}
/>
<style jsx>{`
.error-msg {
Expand Down
27 changes: 18 additions & 9 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
// graph
export const GRAPH_TEXT_FONT_SIZE = 16
export const GRAPH_TEXT_LIEN_HEIGHT = GRAPH_TEXT_FONT_SIZE * 1.5
export const GRAPH_NODE_PADDING_VERTICAL = 4
export const GRAPH_NODE_PADDING_VERTICAL = 2
export const GRAPH_NODE_PADDING_HORIZONTAL = 10
export const GRAPH_NODE_BORDER_RADIUS = 5
export const GRAPH_NODE_MARGIN_VERTICAL = 15
export const GRAPH_NODE_MARGIN_HORIZONTAL = 25
export const GRAPH_GROUP_NODE_PADDING_VERTICAL = 15
export const GRAPH_CHOICE_PADDING_HORIZONTAL = 25
export const GRAPH_CHOICE_PADDING_VERTICAL = 10
export const GRAPH_ROOT_RADIUS = 10
export const GRAPH_ROOT_RADIUS = 5
export const GRAPH_NODE_MIN_WIDTH = 20
export const GRAPH_NODE_MIN_HEIGHT = 26
export const GRAPH_QUANTIFIER_ICON_WIDTH = 28
export const GRAPH_QUANTIFIER_ICON_HEIGHT = 16
export const GRAPH_QUANTIFIER_TEXT_FONTSIZE = 12
export const GRAPH_QUANTIFIER_ICON_MARGIN_VERTICAL = 4
export const GRAPH_NAME_TEXT_FONTSIZE = 12
export const GRAPH_NAME_HEIGHT = 15
export const GRAPH_ICON_SIZE = 18
export const GRAPH_QUANTIFIER_MEASURE_HEIGHT = 16
export const GRAPH_NAME_MEASURE_HEIGHT = 16
export const GRAPH_QUANTIFIER_TEXT_FONTSIZE = 14
export const GRAPH_NAME_TEXT_FONTSIZE = 14
export const GRAPH_QUANTIFIER_HEIGHT = Math.max(
GRAPH_QUANTIFIER_TEXT_FONTSIZE * 1.5,
GRAPH_ICON_SIZE
)
export const GRAPH_NAME_HEIGHT = Math.max(
GRAPH_NAME_TEXT_FONTSIZE * 1.5,
GRAPH_ICON_SIZE
)
export const GRAPH_QUOTE_PADDING = 2

export const GRAPH_PADDING_VERTICAL = 50
export const GRAPH_PADDING_HORIZONTAL = 50
Expand All @@ -32,3 +39,5 @@ export const STORAGE_ESCAPE_BACKSLASH = "escape-backslash"
export const SEARCH_PARAM_REGEX = "r"
export const SEARCH_PARAM_TESTS = "t"
export const SEARCH_PARAM_ESCAPE_BACKSLASH = "e"

export const REGEX_FONT_FAMILY = 'Menlo, Monaco, "Courier New", monospace'
12 changes: 9 additions & 3 deletions src/modules/editor/features/expression/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react"
import { useTranslation } from "react-i18next"
import { useTheme } from "@geist-ui/core"
import Cell from "@/components/cell"
import { REGEX_FONT_FAMILY } from "@/constants"
type Prop = {
regex: string
startIndex: number
Expand All @@ -13,11 +14,16 @@ const Expression: React.FC<Prop> = ({ regex, startIndex, endIndex }) => {
return (
<>
<Cell label={t("Expression")}>
<span>{regex.slice(0, startIndex)}</span>
<span className="highlight">{regex.slice(startIndex, endIndex)}</span>
<span>{regex.slice(endIndex)}</span>
<p className="expression">
<span>{regex.slice(0, startIndex)}</span>
<span className="highlight">{regex.slice(startIndex, endIndex)}</span>
<span>{regex.slice(endIndex)}</span>
</p>
</Cell>
<style jsx>{`
.expression {
font-family: ${REGEX_FONT_FAMILY};
}
.highlight {
border: 2px dashed ${palette.successLight};
border-radius: 4px;
Expand Down
Loading

1 comment on commit f77dbad

@vercel
Copy link

@vercel vercel bot commented on f77dbad May 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

regex-vis – ./

regex-vis.com
regex-vis-git-master-bowen.vercel.app
regex-vis-bowen.vercel.app

Please sign in to comment.