-
Notifications
You must be signed in to change notification settings - Fork 15
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
[UI] Import Jupyter notebook #369
Changes from 2 commits
a0c3991
c55f377
5429184
196568c
6ba96ae
f7fd156
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,7 +28,7 @@ import { | |
} from "d3-force"; | ||
import { YMap } from "yjs/dist/src/types/YMap"; | ||
|
||
import { myNanoId } from "../utils"; | ||
import { myNanoId, level2color } from "../utils"; | ||
|
||
import { | ||
Connection, | ||
|
@@ -56,17 +56,6 @@ type NodeData = { | |
level?: number; | ||
}; | ||
|
||
// FIXME put this into utils | ||
const level2color = { | ||
0: "rgba(187, 222, 251, 0.5)", | ||
1: "rgba(144, 202, 249, 0.5)", | ||
2: "rgba(100, 181, 246, 0.5)", | ||
3: "rgba(66, 165, 245, 0.5)", | ||
4: "rgba(33, 150, 243, 0.5)", | ||
// default: "rgba(255, 255, 255, 0.2)", | ||
default: "rgba(240,240,240,0.25)", | ||
}; | ||
|
||
/** | ||
* Creare the temporary nodes as well as the temporary pods based on the given pod. | ||
* @param pod | ||
|
@@ -142,7 +131,11 @@ function createNewNode(type: "SCOPE" | "CODE" | "RICH", position): Node { | |
// the top-left corner (the reason is unknown). Thus, we have to | ||
// specify the height here. Note that this height is a dummy value; | ||
// the content height will still be adjusted based on content height. | ||
height: 200, | ||
// | ||
// NOTE for import ipynb: we need to specify some reasonable height so that | ||
// the imported pods can be properly laid-out. 130 is a good one. | ||
// This number MUST match the number in Canvas.tsx (refer to "A BIG HACK" in Canvas.tsx). | ||
height: 130, | ||
style: { | ||
width: 300, | ||
// It turns out that this height should not be specified to let the | ||
|
@@ -288,6 +281,12 @@ export interface CanvasSlice { | |
parent: string | ||
) => void; | ||
|
||
importIpynb: ( | ||
position: XYPosition, | ||
repoName: string, | ||
cellList: any[] | ||
) => void; | ||
|
||
setNodeCharWidth: (id: string, width: number) => void; | ||
|
||
pastingNodes?: Node[]; | ||
|
@@ -324,6 +323,8 @@ export interface CanvasSlice { | |
buildNode2Children: () => void; | ||
autoLayout: (scopeId: string) => void; | ||
autoLayoutROOT: () => void; | ||
autoLayoutOnce: boolean; | ||
setAutoLayoutOnce: (b: boolean) => void; | ||
} | ||
|
||
export const createCanvasSlice: StateCreator<MyState, [], [], CanvasSlice> = ( | ||
|
@@ -464,6 +465,70 @@ export const createCanvasSlice: StateCreator<MyState, [], [], CanvasSlice> = ( | |
} | ||
}, | ||
|
||
importIpynb: (position, repoName, cellList) => { | ||
console.log("Sync imported Jupyter notebook cells."); | ||
let nodesMap = get().ydoc.getMap<Node>("pods"); | ||
let scopeNode = createNewNode("SCOPE", position); | ||
nodesMap.set(scopeNode.id, scopeNode); | ||
get().addPod({ | ||
id: scopeNode.id, | ||
name: repoName, | ||
children: [], | ||
parent: "ROOT", | ||
type: scopeNode.type as "CODE" | "SCOPE" | "RICH", | ||
lang: "python", | ||
x: scopeNode.position.x, | ||
y: scopeNode.position.y, | ||
width: scopeNode.width!, | ||
height: scopeNode.height!, | ||
// For my local update, set dirty to true to push to DB. | ||
dirty: true, | ||
pending: true, | ||
}); | ||
if (cellList.length > 0) { | ||
for (let i = 0; i < cellList.length; i++) { | ||
const cell = cellList[i]; | ||
let newPos = { | ||
x: position.x + 50, | ||
y: position.y + 100 + i * 150, | ||
}; | ||
|
||
let node = createNewNode( | ||
cell.cellType == "code" ? "CODE" : "RICH", | ||
newPos | ||
); | ||
let podContent = cell.cellType == "code" ? cell.cellSource : ""; | ||
let podRichContent = cell.cellType == "markdown" ? cell.cellSource : ""; | ||
|
||
nodesMap.set(node.id, node); | ||
get().addPod({ | ||
id: node.id, | ||
children: [], | ||
parent: scopeNode.id, | ||
type: node.type as "CODE" | "SCOPE" | "RICH", | ||
lang: "python", | ||
x: node.position.x, | ||
y: node.position.y, | ||
width: node.width!, | ||
height: node.height!, | ||
content: podContent, | ||
richContent: podRichContent, | ||
// For my local update, set dirty to true to push to DB. | ||
dirty: true, | ||
pending: true, | ||
}); | ||
get().moveIntoScope(node.id, scopeNode.id); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current Those three functions only need to be called once at the end of the ipynbImport action. So let's add a moveIntoScopeLight() {...}
moveIntoScope() {
moveIntoScopeLight();
get().adjustLevel();
get().updateView();
get().buildNode2Children();
}
importIpynb() {
...
for() {...
moveIntoScopeLight()
}
get().adjustLevel();
get().updateView();
get().buildNode2Children();
...
} |
||
} | ||
} | ||
|
||
get().buildNode2Children(); | ||
// Set initial width as about 30 characters. | ||
get().setNodeCharWidth(scopeNode.id, 30); | ||
get().updateView(); | ||
}, | ||
autoLayoutOnce: false, | ||
setAutoLayoutOnce: (b) => set({ autoLayoutOnce: b }), | ||
|
||
setNodeCharWidth: (id, width) => { | ||
let nodesMap = get().ydoc.getMap<Node>("pods"); | ||
let node = nodesMap.get(id); | ||
|
@@ -1003,7 +1068,7 @@ export const createCanvasSlice: StateCreator<MyState, [], [], CanvasSlice> = ( | |
/** | ||
* Use d3-force to auto layout the nodes. | ||
*/ | ||
autoLayout: (scopeId) => { | ||
autoLayout: async (scopeId) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was for debugging. Not needed. |
||
// 1. get all the nodes and edges in the scope | ||
let nodesMap = get().ydoc.getMap<Node>("pods"); | ||
const nodes = get().nodes.filter( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This magic number
130
must be kept consistent with the130
inCanvas.tsx
. Let's store it in one global variable and access it in both files. Also, we can use some floating number to mark it special, e.g.,136.66
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given it's a hacky way to apply autolayout, I think we can use 130 here. We need to find a better way for autolayer eventually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Precisely because it is hacky, we want to avoid breaking it accidentally, by:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you have changed to a global variable. The floating number isn't that critical (as long as it's not 120).