CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-cytoscape

Graph theory library for analysis and visualisation of network data with interactive rendering capabilities

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

styling-system.mddocs/

Styling System

CSS-like styling system with selectors, properties, and themes. Supports dynamic styling, animations, and complex visual customization for nodes, edges, and the core canvas.

Capabilities

Stylesheet Definition

Define styles using CSS-like syntax with selectors and property blocks.

interface StylesheetJson extends Array<StyleRule> {}

interface StyleRule {
  /**
   * CSS-like selector for targeting elements
   */
  selector: string;
  
  /**
   * Style properties to apply
   */
  style: StyleProperties;
}

/**
 * Create stylesheet from array of style rules
 */
const stylesheet: StylesheetJson = [
  {
    selector: 'node',
    style: {
      'background-color': '#666',
      'label': 'data(id)'
    }
  },
  {
    selector: 'edge',
    style: {
      'width': 3,
      'line-color': '#ccc'
    }
  }
];

Core Styling Methods

Apply and manage styles on the core instance and collections.

interface Core {
  /**
   * Get or set stylesheet
   * @param stylesheet - Stylesheet to apply (optional)
   * @returns Current stylesheet or Core instance
   */
  style(stylesheet?: StylesheetJson): StylesheetJson | Core;
  
  /**
   * Get stylesheet object
   * @returns Stylesheet instance
   */
  stylesheet(): Stylesheet;
  
  /**
   * Update style calculations (call after dynamic changes)
   * @returns Core instance
   */
  updateStyle(): Core;
}

interface Collection {
  /**
   * Get or set style property
   * @param property - CSS property name
   * @param value - Property value (optional)
   * @returns Property value or Collection
   */
  style(property: string, value?: any): any | Collection;
  
  /**
   * Get or set multiple style properties
   * @param properties - Object with property-value pairs
   * @returns Collection for chaining
   */
  style(properties: StyleProperties): Collection;
  
  /**
   * Remove style properties (revert to stylesheet)
   * @param properties - Properties to remove (optional, removes all if not specified)
   * @returns Collection for chaining
   */
  removeStyle(properties?: string | string[]): Collection;
}

Selectors

Target specific elements using CSS-like selectors.

/**
 * Basic selectors
 */
"node"                    // All nodes
"edge"                    // All edges
"*"                       // All elements

/**
 * ID selectors
 */
"#mynode"                 // Element with id 'mynode'

/**
 * Class selectors
 */
".highlighted"            // Elements with class 'highlighted'
".important.active"       // Elements with both classes

/**
 * Data selectors
 */
"[weight]"               // Elements with 'weight' data property
"[weight > 10]"          // Elements where weight > 10
"[type = 'user']"        // Elements where type equals 'user'
"[name *= 'john']"       // Elements where name contains 'john'

/**
 * Compound selectors
 */
"node.active"            // Active nodes
"edge[weight > 5]"       // Heavy edges
"node#start.important"   // Important start node

/**
 * State selectors
 */
":selected"              // Selected elements
":unselected"            // Unselected elements
":locked"                // Locked elements
":unlocked"              // Unlocked elements
":grabbed"               // Currently grabbed elements
":free"                  // Not grabbed elements
":removed"               // Removed elements
":inside"                // Elements inside compound nodes
":grabbable"             // Grabbable elements
":ungrabbable"           // Ungrabbable elements

/**
 * Compound graph selectors
 */
":parent"                // Parent (compound) nodes
":childless"             // Nodes without children
":child"                 // Child nodes
":orphan"                // Nodes without parents

/**
 * Edge-specific selectors
 */
":simple"                // Simple edges (no loops, no multiple edges)
":loop"                  // Self-loops

/**
 * Combination selectors
 */
"node, edge"             // Nodes OR edges (union)
"node.active edge"       // Edges connected to active nodes

Usage Examples:

// Style all nodes
const stylesheet = [
  {
    selector: 'node',
    style: {
      'background-color': '#0074D9',
      'width': 20,
      'height': 20,
      'label': 'data(name)'
    }
  },
  
  // Style selected nodes differently
  {
    selector: 'node:selected',
    style: {
      'background-color': '#FF4136',
      'border-width': 3,
      'border-color': '#FFDC00'
    }
  },
  
  // Style edges by weight
  {
    selector: 'edge[weight > 5]',
    style: {
      'width': 4,
      'line-color': '#FF851B'
    }
  }
];

Node Style Properties

Comprehensive styling options for nodes.

interface NodeStyleProperties {
  // Dimensions
  'width'?: number | string;
  'height'?: number | string;
  'shape'?: 'ellipse' | 'triangle' | 'round-triangle' | 'rectangle' | 'round-rectangle' | 
           'bottom-round-rectangle' | 'cut-rectangle' | 'barrel' | 'rhomboid' | 'diamond' | 
           'round-diamond' | 'pentagon' | 'round-pentagon' | 'hexagon' | 'round-hexagon' | 
           'concave-hexagon' | 'heptagon' | 'round-heptagon' | 'octagon' | 'round-octagon' | 
           'star' | 'tag' | 'round-tag' | 'vee';
  
  // Background
  'background-color'?: string;
  'background-opacity'?: number;
  'background-blacken'?: number;
  'background-image'?: string | string[];
  'background-image-opacity'?: number | number[];
  'background-fit'?: 'none' | 'contain' | 'cover';
  'background-repeat'?: 'no-repeat' | 'repeat-x' | 'repeat-y' | 'repeat';
  'background-position-x'?: string | number;
  'background-position-y'?: string | number;
  'background-width'?: string | number;
  'background-height'?: string | number;
  'background-clip'?: 'none' | 'node';
  
  // Border
  'border-width'?: number;
  'border-style'?: 'solid' | 'dotted' | 'dashed' | 'double';
  'border-color'?: string;
  'border-opacity'?: number;
  
  // Outline (selection indicator)
  'outline-width'?: number;
  'outline-color'?: string;
  'outline-opacity'?: number;
  'outline-offset'?: number;
  
  // Padding (for compound nodes)
  'padding'?: string | number;
  'padding-left'?: string | number;
  'padding-right'?: string | number;
  'padding-top'?: string | number;
  'padding-bottom'?: string | number;
  
  // Compound node specific
  'compound-sizing-wrt-labels'?: 'include' | 'exclude';
  
  // Position
  'position'?: 'origin';
  
  // Visibility
  'opacity'?: number;
  'display'?: 'element' | 'none';
  'visibility'?: 'visible' | 'hidden';
  'z-index'?: number;
  'z-compound-depth'?: 'bottom' | 'orphan' | 'auto' | number;
  
  // Interactivity
  'min-zoomed-font-size'?: number;
  'overlay-color'?: string;
  'overlay-padding'?: number;
  'overlay-opacity'?: number;
  'underlay-color'?: string;
  'underlay-padding'?: number;
  'underlay-opacity'?: number;
  'underlay-shape'?: 'ellipse' | 'round-rectangle';
  
  // Ghost (dragging preview)
  'ghost'?: 'yes' | 'no';
  'ghost-offset-y'?: number;
  'ghost-offset-x'?: number;
  'ghost-opacity'?: number;
}

Edge Style Properties

Styling options for edges including arrows, curves, and labels.

interface EdgeStyleProperties {
  // Line
  'width'?: number;
  'line-color'?: string;
  'line-style'?: 'solid' | 'dotted' | 'dashed';
  'line-cap'?: 'butt' | 'round' | 'square';
  'line-opacity'?: number;
  'line-dash-pattern'?: number[];
  'line-dash-offset'?: number;
  
  // Curve
  'curve-style'?: 'straight' | 'haystack' | 'bezier' | 'unbundled-bezier' | 
                  'segments' | 'taxi' | 'round-taxi';
  'control-point-step-size'?: number;
  'control-point-distances'?: number | number[];
  'control-point-weights'?: number | number[];
  'segment-distances'?: number | number[];
  'segment-weights'?: number | number[];
  'taxi-turn'?: string;
  'taxi-turn-min-distance'?: number;
  'taxi-direction'?: 'auto' | 'up' | 'down' | 'left' | 'right' | 'downward' | 'upward' | 
                     'leftward' | 'rightward' | 'vertical' | 'horizontal';
  
  // Source arrow
  'source-arrow-color'?: string;
  'source-arrow-shape'?: 'triangle' | 'triangle-tee' | 'circle-triangle' | 'triangle-cross' | 
                         'triangle-backcurve' | 'vee' | 'tee' | 'square' | 'circle' | 
                         'diamond' | 'chevron' | 'none';
  'source-arrow-width'?: number;
  'source-arrow-height'?: number;
  
  // Target arrow
  'target-arrow-color'?: string;
  'target-arrow-shape'?: 'triangle' | 'triangle-tee' | 'circle-triangle' | 'triangle-cross' | 
                         'triangle-backcurve' | 'vee' | 'tee' | 'square' | 'circle' | 
                         'diamond' | 'chevron' | 'none';
  'target-arrow-width'?: number;
  'target-arrow-height'?: number;
  
  // Mid arrow
  'mid-source-arrow-color'?: string;
  'mid-source-arrow-shape'?: string;
  'mid-source-arrow-width'?: number;
  'mid-source-arrow-height'?: number;
  'mid-target-arrow-color'?: string;
  'mid-target-arrow-shape'?: string;
  'mid-target-arrow-width'?: number;
  'mid-target-arrow-height'?: number;
  
  // Visibility and interaction
  'opacity'?: number;
  'display'?: 'element' | 'none';
  'visibility'?: 'visible' | 'hidden';
  'z-index'?: number;
  'overlay-color'?: string;
  'overlay-padding'?: number;
  'overlay-opacity'?: number;
  'underlay-color'?: string;
  'underlay-padding'?: number;
  'underlay-opacity'?: number;
  
  // Selection
  'selection-box-color'?: string;
  'selection-box-border-color'?: string;
  'selection-box-border-width'?: number;
  'selection-box-opacity'?: number;
  
  // Loop edges
  'loop-direction'?: string;
  'loop-sweep'?: string;
  
  // Haystack edges
  'haystack-radius'?: number;
  
  // Ghost
  'ghost'?: 'yes' | 'no';
  'ghost-offset-y'?: number;
  'ghost-offset-x'?: number;
  'ghost-opacity'?: number;
}

Label Style Properties

Text labels for nodes and edges with extensive typography control.

interface LabelStyleProperties {
  // Content
  'label'?: string;
  
  // Typography
  'color'?: string;
  'font-family'?: string;
  'font-size'?: number | string;
  'font-style'?: 'normal' | 'italic' | 'oblique';
  'font-variant'?: 'normal' | 'small-caps';
  'font-weight'?: 'normal' | 'bold' | 'bolder' | 'lighter' | number;
  'text-transform'?: 'none' | 'uppercase' | 'lowercase' 'capitalize';
  
  // Alignment
  'text-halign'?: 'left' | 'center' | 'right';
  'text-valign'?: 'top' | 'center' | 'bottom';
  
  // Positioning
  'text-margin-x'?: number;
  'text-margin-y'?: number;
  'text-rotation'?: number | 'autorotate' | 'none';
  
  // Wrapping
  'text-wrap'?: 'none' | 'wrap' | 'ellipsis';
  'text-max-width'?: number | string;
  'text-overflow-wrap'?: 'whitespace' | 'anywhere';
  'text-justification'?: 'left' | 'center' | 'right' | 'auto';
  
  // Background
  'text-background-color'?: string;
  'text-background-opacity'?: number;
  'text-background-shape'?: 'rectangle' | 'round-rectangle';
  'text-background-padding'?: number;
  
  // Border
  'text-border-color'?: string;
  'text-border-width'?: number;
  'text-border-style'?: 'solid' | 'dotted' | 'dashed' | 'double';
  'text-border-opacity'?: number;
  
  // Outline
  'text-outline-color'?: string;
  'text-outline-width'?: number;
  'text-outline-opacity'?: number;
  
  // Shadow
  'text-shadow-blur'?: number;
  'text-shadow-color'?: string;
  'text-shadow-offset-x'?: number;
  'text-shadow-offset-y'?: number;
  'text-shadow-opacity'?: number;
  
  // Visibility
  'text-opacity'?: number;
  'min-zoomed-font-size'?: number;
  
  // Edge label positioning
  'source-text-offset'?: number;
  'target-text-offset'?: number;
  'source-text-rotation'?: number | 'autorotate';
  'target-text-rotation'?: number | 'autorotate';
}

Core Style Properties

Styling for the core canvas and global elements.

interface CoreStyleProperties {
  // Background
  'background-color'?: string;
  'background-opacity'?: number;
  'background-image'?: string;
  'background-fit'?: 'none' | 'contain' | 'cover';
  'background-repeat'?: 'no-repeat' | 'repeat-x' | 'repeat-y' | 'repeat';
  'background-position-x'?: string | number;
  'background-position-y'?: string | number;
  'background-width'?: string | number;
  'background-height'?: string | number;
  
  // Selection box
  'selection-box-color'?: string;
  'selection-box-border-color'?: string;
  'selection-box-border-width'?: number;
  'selection-box-opacity'?: number;
  
  // Active background (when panning/zooming)
  'active-bg-color'?: string;
  'active-bg-opacity'?: number;
  'active-bg-size'?: number;
  
  // Outside texture (for very large graphs)
  'outside-texture-bg-color'?: string;
  'outside-texture-bg-opacity'?: number;
}

Dynamic Styling

Apply styles programmatically and respond to data changes.

/**
 * Data-driven styling using mappers
 */

// Map data to style values
const stylesheet = [
  {
    selector: 'node',
    style: {
      'width': 'mapData(weight, 0, 100, 10, 50)',
      'height': 'mapData(weight, 0, 100, 10, 50)',
      'background-color': 'mapData(score, 0, 1, blue, red)'
    }
  }
];

// Conditional styling
const conditionalStyle = [
  {
    selector: 'node[type = "user"]',
    style: {
      'shape': 'round-rectangle',
      'background-color': '#3498db'
    }
  },
  {
    selector: 'node[type = "group"]',
    style: {
      'shape': 'hexagon',
      'background-color': '#e74c3c'
    }
  }
];

// Style based on degree
cy.nodes().forEach(node => {
  const degree = node.degree();
  node.style({
    'width': Math.max(20, degree * 5),
    'height': Math.max(20, degree * 5),
    'background-color': degree > 3 ? 'red' : 'blue'
  });
});

CSS Classes

Manage CSS classes for reusable styling patterns.

interface Collection {
  /**
   * Add CSS classes to elements
   * @param classes - Space-separated class names
   * @returns Collection for chaining
   */
  addClass(classes: string): Collection;
  
  /**
   * Remove CSS classes from elements
   * @param classes - Space-separated class names (optional, removes all if not specified)
   * @returns Collection for chaining
   */
  removeClass(classes?: string): Collection;
  
  /**
   * Toggle CSS classes on elements
   * @param classes - Space-separated class names
   * @param state - Force toggle state (optional)
   * @returns Collection for chaining
   */
  toggleClass(classes: string, state?: boolean): Collection;
  
  /**
   * Check if elements have CSS class
   * @param className - Class name to check
   * @returns True if all elements have the class
   */
  hasClass(className: string): boolean;
  
  /**
   * Get all classes on first element
   * @returns Array of class names
   */
  classes(): string[];
}

Usage Examples:

// Define classes in stylesheet
const stylesheet = [
  {
    selector: '.highlighted',
    style: {
      'background-color': 'yellow',
      'border-width': 3,
      'border-color': 'orange'
    }
  },
  {
    selector: '.faded',
    style: {
      'opacity': 0.3
    }
  }
];

// Apply classes dynamically
cy.nodes().addClass('highlighted');
cy.edges().addClass('faded');

// Toggle classes based on selection
cy.on('select', 'node', function(evt) {
  evt.target.addClass('selected');
});

cy.on('unselect', 'node', function(evt) {
  evt.target.removeClass('selected');
});

Animation and Transitions

Animate style changes for smooth visual transitions.

interface Collection {
  /**
   * Animate style changes
   * @param properties - Style properties to animate
   * @param options - Animation options
   * @returns Promise that resolves when animation completes
   */
  animate(properties: StyleProperties, options?: AnimationOptions): Promise<Collection>;
}

interface AnimationOptions {
  /**
   * Animation duration in milliseconds
   */
  duration?: number;
  
  /**
   * Easing function
   */
  easing?: string;
  
  /**
   * Delay before animation starts
   */
  delay?: number;
  
  /**
   * Callback when animation completes
   */
  complete?: () => void;
  
  /**
   * Callback for each animation step
   */
  step?: (now: number, tween: any) => void;
  
  /**
   * Animation queue name
   */
  queue?: string | boolean;
}

Usage Examples:

// Animate node color change
node.animate({
  'background-color': 'red',
  'width': 50,
  'height': 50
}, {
  duration: 1000,
  easing: 'ease-in-out'
});

// Chain animations
node.animate({
  'background-color': 'blue'
}, 500).then(() => {
  return node.animate({
    'background-color': 'green'
  }, 500);
});

// Animate multiple properties
cy.nodes().animate({
  'background-color': 'purple',
  'width': 'mapData(degree, 0, 10, 20, 60)'
}, {
  duration: 2000,
  complete: () => console.log('Animation finished')
});

Style Utilities

Helper functions and advanced styling techniques.

/**
 * Style utility functions
 */

// Get computed style value
const computedColor = node.style('background-color');
const computedWidth = node.style('width');

// Check if style is applied
const hasCustomColor = node.style('background-color') !== node.removeClass().style('background-color');

// Reset styles to stylesheet defaults
node.removeStyle();
node.removeStyle(['background-color', 'width']);

// Batch style operations for performance
cy.batch(() => {
  cy.nodes().style('background-color', 'blue');
  cy.edges().style('line-color', 'red');
});

// Style templates
function applyNodeTemplate(nodes, template) {
  nodes.style(template);
}

applyNodeTemplate(cy.nodes('.important'), {
  'background-color': '#ff6b6b',
  'border-width': 3,
  'border-color': '#4ecdc4'
});

Install with Tessl CLI

npx tessl i tessl/npm-cytoscape

docs

core-management.md

element-collections.md

event-system.md

extensions.md

graph-algorithms.md

index.md

layout-system.md

styling-system.md

tile.json