Skip to content

Graph Response Area (Re-opened)#8

Open
HongleiGu wants to merge 28 commits intomainfrom
main
Open

Graph Response Area (Re-opened)#8
HongleiGu wants to merge 28 commits intomainfrom
main

Conversation

@HongleiGu
Copy link

Sorry for messing up with the branches, I'll try to migrate the PR content here

HongleiGu and others added 28 commits January 16, 2026 01:00
… fix, I dont think it should be the same with Input
…ed to add more info for teacher mode and find ways to test backend connect, schema may need fix as JSON.stringfy can walk pass the zod schema check
feat: implement GraphQL data fetching and add live preview functional…
… and corrected data logic for sending response and answer to backend
@HarrySu123
Copy link

Key features:

  • allows student to add nodes via inbuilt graph editor

  • allows student to draw in nodes and edges via graph editor draw mode

  • allows teacher to choose what sort of evaluation they want to apply to student's response , using the configuration panel in teacher's answer area

  • allows teacher to choose whether graph will be directed or not in teacher's answer area

  • currently only compatible with graphEval evaluation function

All changes done within src/types/Graph

Code structure

src/types/Graph/components.tsx

defines the react configuration panel component that allows the teacher to choose the sort of evaluation that should occur.

src/types/Graph/GraphFeedbackPanel.tsx

Currently unused, but allows potential implementation of feedbacks via preview. Not sure what sort of preview feedback would be beneficial for students

src/types/Graph/ItemPropertiesPanel.tsx

defines the sidebar of the graph editor, which allows node creation, deletion, and switch for turning on drawing mode.

src/types/Graph/Graph.component.tsx

defines the main interactive graph editor component, uses Cytoscape.js to redner and manage the graph, and uses Paper.js to allow drawing detection in drawing mode.

src/types/Graph/validateGraph.ts

Currently unused, allows immediate simple check for the graph, but this can be done in backend if needed. It is only here as an idea for preview.

Copy link
Member

@m-messer m-messer left a comment

Choose a reason for hiding this comment

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

Thanks for your work on this! Some minor comments, mainly on refactoring a style.

How much of this code is duplicated in FSA? Might it be worth commenting on those files?

Copy link
Member

Choose a reason for hiding this comment

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

This is the wrong Md file.

Copy link
Author

Choose a reason for hiding this comment

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

This is the wrong Md file.

yes absolutely, I wrote this when doing FSA, and it was copied to Graph and ignored, I'll fix this in the following commits

Copy link
Member

Choose a reason for hiding this comment

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

Should this be ignored or just not added to the commit? (Do we want to ignore these in the future?)

Copy link
Author

Choose a reason for hiding this comment

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

I think this is here by accident, FSA and PropositionalLogic never existed in this repo, will definitely fix this

Choose a reason for hiding this comment

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

Oops, this was done by me, I had an issue with my laptop where I couldn't open more than 1 vscode open at the same time, but I wanted to see the code for PL config panel and FSA graph to take inspiration for Graph. Fixed now.

Copy link
Member

Choose a reason for hiding this comment

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

References FSA.

Choose a reason for hiding this comment

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

Same issue as FSA.md, simple fix

'ESSAY',
'CODE',
'MILKDOWN',
'LIKERT',
Copy link
Member

Choose a reason for hiding this comment

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

Why remove these? If removed also remove the imports?

}

class VoidResponseAreaTub extends ResponseAreaTub {
// public readonly responseType = 'VOID'
Copy link
Member

Choose a reason for hiding this comment

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

Remove commented out code

import { Graph, SimpleGraph } from './type'

// BackendGraph type: what backend expects
export interface BackendGraph {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe add some explaination of why this is needed here.

directed: provided.directed ?? false,
weighted: provided.weighted ?? false,
multigraph: provided.multigraph ?? false,
evaluation_type: Array.isArray(legacyEval)
Copy link
Member

Choose a reason for hiding this comment

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

Instead of multiline tenary, use if/else?

Choose a reason for hiding this comment

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

I think tenary for directed weighted and multigraph makes it easier to read, if you believe it is better to use if/else we can change it to that.

Copy link
Member

Choose a reason for hiding this comment

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

I may have put the comment on the wrong line here. I think there was a tenary that was formatted across multiple lines. Here it is fine.

import { Graph, Node, Edge, GraphFeedback, CheckPhase } from './type'

/* ----------------------------- Local Styles ----------------------------- */
export const useLocalStyles = makeStyles()((theme) => ({
Copy link
Member

Choose a reason for hiding this comment

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

Should these style not be in the styles file or somewhere similar?

const cy: Core = cytoscape({
container: containerRef.current,
layout: { name: 'preset' },
style: [
Copy link
Member

Choose a reason for hiding this comment

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

Should these styles be in a style file or similar?

return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
<div
style={{
Copy link
Member

Choose a reason for hiding this comment

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

Style in the style file?

"typescript": "^5.4.5",
"typescript-eslint": "^7.11.0",
"vite": "^7.0.0"
"vite": "^5.4.11"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why to download a library? Could 7.0.0 be kept?

multigraph: config.multigraph,
evaluation_type: config.evaluation_type,
}
console.log('[GraphTub] sending to backend:', flatAnswer)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are you gonna keep the console.log ?
Many developers prefer to remove any console.log before merging.

Comment on lines +449 to +451
const isCircle = diameter > 20 &&
strokeLength > circumference * 0.3 &&
distance < diameter * 0.5
Copy link
Collaborator

Choose a reason for hiding this comment

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

These 3 constants should be defined as constants, even if local constants in this file.

target: e.target().id(),
label: (e.data('label') as string) ?? '',
metadata: {},
weight: 0
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are you accepting weighted graphs? If so, should it preserve the original weight? Something like parseFloat(e.data('weight')) ...

Choose a reason for hiding this comment

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

Weighted graphs are not currently accepted, none of the evaluation in the backend requires the graph to be weighted. However evaluation that requires weight could be an interesting thing to be implemented in the future, where the response area could easily allow weighted graphs to be made.

Comment on lines +25 to +34
static toSimple(graph: Graph): SimpleGraph {
return {
nodes: graph.nodes.map(n => `${n.id}|${n.label || ''}|${n.x || 0}|${n.y || 0}`),
edges: graph.edges.map(e => `${e.source}|${e.target}|${e.weight || 1}|${e.label || ''}`),
directed: graph.directed,
weighted: graph.weighted,
multigraph: graph.multigraph,
evaluation_type: [],
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

GraphConverter.toSimple() and GraphConverter.fromSimple() in utils.ts seems to do the same as toSimpleGraph() and fromSimpleGraph() in type.ts
Am I right? Should some refactoring make sense?

Comment on lines +158 to +183
// -----------------------------
// Compressed Graph: JSON-stringified nodes/edges
// -----------------------------
export const CompressedGraphSchema = z.object({
nodes: z.array(z.string()), // JSON.stringify(nodes)
edges: z.array(z.string()), // JSON.stringify(edges)
directed: z.boolean().default(false),
weighted: z.boolean().default(false),
multigraph: z.boolean().default(false),
name: z.string().optional(),
metadata: z.record(z.any()).optional().default({}),
});

export type CompressedGraph = z.infer<typeof CompressedGraphSchema>

// -----------------------------
// Example: compress function
// -----------------------------
export function compressGraph(graph: z.infer<typeof GraphSchema>) {
return {
...graph,
nodes: JSON.stringify(graph.nodes),
edges: JSON.stringify(graph.edges),
};
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

CompressedGraphSchema, CompressedGraph, and compressGraph are never imported or used anywhere in the codebase. Like the intentionally-unused files you mentioned in your PR description, if this is a future idea, please add a comment explaining why it exists. Otherwise, remove

@HongleiGu
Copy link
Author

Thanks for your work on this! Some minor comments, mainly on refactoring a style.

How much of this code is duplicated in FSA? Might it be worth commenting on those files?

Almost everything is copied from FSA, the only difference of graph and FSA is the feedback and the answer schema, which both use a temporary frontend-type to walk around the two-layer json requirement of the answer

Therefore if needed, we can try to unify the type and make graph and FSA combined, however, in this assignment we probably wont have time to finish this (Given its near the end and the exams)

@m-messer
Copy link
Member

m-messer commented Mar 4, 2026

Thanks for your work on this! Some minor comments, mainly on refactoring a style.
How much of this code is duplicated in FSA? Might it be worth commenting on those files?

Almost everything is copied from FSA, the only difference of graph and FSA is the feedback and the answer schema, which both use a temporary frontend-type to walk around the two-layer json requirement of the answer

Therefore if needed, we can try to unify the type and make graph and FSA combined, however, in this assignment we probably wont have time to finish this (Given its near the end and the exams)

Thanks for confirming! No need to merge before the deadlines, it's just good to know if/when we pull the changes into the application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants