CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-gojs

Interactive diagrams, charts, and graphs library for creating flowcharts, org charts, UML, BPMN, and hundreds of other diagram types with rich layouts and tools.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

interactive-tools.mddocs/

Interactive Tools

GoJS provides a comprehensive tool system for handling user interactions like selection, dragging, linking, and editing. The tool system is managed by the ToolManager and provides both built-in tools and extensibility for custom interactions.

Capabilities

ToolManager extends Tool

Central coordinator for all diagram tools, managing tool activation and user input routing.

class ToolManager extends Tool {
  // Selection Tools
  clickSelectingTool: ClickSelectingTool;
  dragSelectingTool: DragSelectingTool;
  
  // Movement and Manipulation Tools
  draggingTool: DraggingTool;
  resizingTool: ResizingTool;
  rotatingTool: RotatingTool;
  
  // Link Tools
  linkingTool: LinkingTool;
  relinkingTool: RelinkingTool;
  linkReshapingTool: LinkReshapingTool;
  
  // Editing Tools
  textEditingTool: TextEditingTool;
  contextMenuTool: ContextMenuTool;
  
  // Navigation Tools
  panningTool: PanningTool;
  
  // Custom Tools
  mouseDownTools: List<Tool>;
  mouseMoveTools: List<Tool>;
  mouseUpTools: List<Tool>;
  
  // Timing and Behavior
  hoverDelay: number;
  toolTipDuration: number;
  standardMouseOver: (() => void) | null;
  standardMouseOut: (() => void) | null;
  
  // Input State
  currentTool: Tool;
  defaultTool: Tool;
  mouseDownPoint: Point;
  lastInput: InputEvent;
}

DraggingTool extends Tool

Handles moving parts by dragging with support for copying, grouping, and grid snapping.

class DraggingTool extends Tool {
  // Drag Behavior
  copiesEffectively: boolean;
  copiesTree: boolean;
  dragsTree: boolean;
  dragsLink: boolean;
  
  // Grid and Snapping
  isGridSnapEnabled: boolean;
  gridSnapCellSize: Size;
  gridSnapCellSpot: Spot;
  gridSnapOrigin: Point;
  
  // Drag State
  draggedParts: Map<Part, DraggingInfo>;
  copiedParts: Map<Part, Part>;
  
  // Validation
  mayMove(): boolean;
  mayCopy(): boolean;
  computeEffectiveCollection(parts: Iterable<Part>): Map<Part, DraggingInfo>;
  
  // Methods
  doActivate(): void;
  doMouseMove(): void;
  doMouseUp(): void;
  doDragOver(pt: Point, obj: GraphObject): void;
  doDropOnto(pt: Point, obj: GraphObject): void;
}

interface DraggingInfo {
  point: Point;
  part: Part;
}

LinkingTool extends Tool

Creates new links by dragging from one node to another with validation and visual feedback.

class LinkingTool extends Tool {
  // Link Creation
  temporaryLink: Link;
  temporaryFromNode: Node;
  temporaryFromPort: GraphObject;
  temporaryToNode: Node;
  temporaryToPort: GraphObject;
  
  // Behavior
  direction: LinkingDirection;
  portGravity: number;
  delay: number;
  
  // Validation
  isLinkValid(fromnode: Node, fromport: GraphObject, tonode: Node, toport: GraphObject): boolean;
  isUnconnectedLinkValid(link: Link): boolean;
  
  // Visual Feedback
  temporaryTool: Tool;
  archetypeLinkData: ObjectData;
  
  // Methods
  findLinkablePort(): GraphObject | null;
  insertLink(fromnode: Node, fromport: GraphObject, tonode: Node, toport: GraphObject): Link | null;
}

enum LinkingDirection {
  Either = 'Either',
  ForwardsOnly = 'ForwardsOnly',
  BackwardsOnly = 'BackwardsOnly'
}

ResizingTool extends Tool

Provides resize handles for changing part dimensions with aspect ratio and size constraints.

class ResizingTool extends Tool {
  // Handle Configuration
  handleArchetype: GraphObject;
  minSize: Size;
  maxSize: Size;
  
  // Resize Behavior
  cellSize: Size;
  isGridSnapEnabled: boolean;
  oppositePoint: Point;
  
  // State
  handle: GraphObject;
  adornedObject: GraphObject;
  originalBounds: Rect;
  
  // Methods
  updateAdornments(part: Part): void;
  resize(newr: Rect): void;
  computeResize(p: Point): Size;
  computeMinPoolSize(group: Group): Size;
}

TextEditingTool extends Tool

Handles in-place text editing with validation and custom editor support.

class TextEditingTool extends Tool {
  // Editor Configuration
  textBlock: TextBlock;
  defaultTextEditor: HTMLElement;
  starting: TextEditingStarting;
  state: TextEditingState;
  
  // Validation
  textValidation: ((tb: TextBlock, oldstr: string, newstr: string) => boolean) | null;
  
  // Events
  selectsTextOnActivate: boolean;
  
  // Methods
  doActivate(): void;
  acceptText(reason: TextEditingAccept): boolean;
  doMouseUp(): void;
  
  // State Management
  isActive: boolean;
  currentTextEditor: HTMLElement;
}

enum TextEditingStarting {
  SingleClick = 'SingleClick',
  SingleClickSelected = 'SingleClickSelected',  
  DoubleClick = 'DoubleClick'
}

enum TextEditingState {
  None = 'None',
  Active = 'Active',
  Editing = 'Editing'
}

enum TextEditingAccept {
  Enter = 'Enter',
  Tab = 'Tab',
  LostFocus = 'LostFocus',
  MouseDown = 'MouseDown',
  NotCancelled = 'NotCancelled'
}

Usage Examples:

// Configure text editing behavior
diagram.toolManager.textEditingTool.starting = go.TextEditingStarting.SingleClick;
diagram.toolManager.textEditingTool.selectsTextOnActivate = true;

// Custom text validation
diagram.toolManager.textEditingTool.textValidation = (tb, oldstr, newstr) => {
  // Limit text length and disallow empty strings
  return newstr.length > 0 && newstr.length <= 50;
};

Selection Tools

Tools for selecting parts using click or drag operations.

class ClickSelectingTool extends Tool {
  standardMouseSelect(): void;
  selectPart(part: Part, extend: boolean): void;
}

class DragSelectingTool extends Tool {  
  box: Part;
  delay: number;
  isPartialInclusion: boolean;
  
  computeBoxBounds(): Rect;
  selectInBox(r: Rect): void;
}

Usage Examples:

// Configure selection behavior
diagram.toolManager.clickSelectingTool.standardMouseSelect = function() {
  // Custom selection logic
  const part = this.findSelectableObject();
  if (part) {
    if (this.diagram.lastInput.control) {
      // Toggle selection with Ctrl
      part.isSelected = !part.isSelected;
    } else {
      // Normal selection
      this.diagram.select(part);
    }
  }
};

// Customize drag selection box
diagram.toolManager.dragSelectingTool.box = 
  new go.Part()
    .add(new go.Shape({
      name: 'SHAPE',
      fill: 'rgba(0,128,255,0.3)',
      stroke: 'blue'
    }));

Common Patterns

Custom Tool Implementation

class CustomClickTool extends go.Tool {
  constructor() {
    super();
    this.name = 'CustomClick';
  }
  
  canStart(): boolean {
    if (!super.canStart()) return false;
    
    const diagram = this.diagram;
    const e = diagram.lastInput;
    
    // Only start on double-click
    return e.clickCount >= 2;
  }
  
  doMouseUp(): void {
    const obj = this.diagram.findObjectAt(this.diagram.lastInput.documentPoint);
    if (obj && obj.part) {
      console.log('Double-clicked on:', obj.part.data);
      // Custom double-click logic here
    }
    
    this.stopTool();
  }
}

// Add custom tool to diagram
diagram.toolManager.mouseDownTools.insertAt(0, new CustomClickTool());

Tool State Management

// Check tool states
if (diagram.toolManager.draggingTool.isActive) {
  console.log('Currently dragging');
}

if (diagram.toolManager.textEditingTool.state === go.TextEditingState.Editing) {
  console.log('Currently editing text');
}

// Programmatically activate tools
if (diagram.toolManager.linkingTool.canStart()) {
  diagram.toolManager.linkingTool.doStart();
}

Tool Customization

// Customize dragging behavior
diagram.toolManager.draggingTool.isGridSnapEnabled = true;
diagram.toolManager.draggingTool.gridSnapCellSize = new go.Size(20, 20);
diagram.toolManager.draggingTool.copiesEffectively = true;

// Custom linking validation
diagram.toolManager.linkingTool.isLinkValid = function(fromnode, fromport, tonode, toport) {
  // Prevent linking to same node
  if (fromnode === tonode) return false;
  
  // Only allow certain node types to connect
  const fromType = fromnode.data.type;
  const toType = tonode.data.type;
  
  return (fromType === 'source' && toType === 'process') ||
         (fromType === 'process' && toType === 'sink');
};

// Custom resize constraints
diagram.toolManager.resizingTool.minSize = new go.Size(20, 20);
diagram.toolManager.resizingTool.maxSize = new go.Size(200, 200);

docs

binding-animation.md

core-diagram.md

data-models.md

geometry-collections.md

graphobject-hierarchy.md

index.md

interactive-tools.md

layout-system.md

theme-management.md

visual-elements.md

tile.json