Karana.KUtils.visjs

Contents

Karana.KUtils.visjs#

Module containing classes and functions to visualize dot graphs.

Classes#

Node

Represents a node in the network graph.

Edge

Represents an edge between nodes in the network graph.

NetworkGraph

Represents a graph with nodes, edges, and global options.

Button

Custom button to be displayed in the UI.

FontStyleOptions

Style options for font variants.

FontOptions

Font options for labels.

ShadowOptions

Shadow options for nodes and edges.

ShapeProperties

Properties for custom node shapes.

WidthConstraintOptions

Width constraint options for nodes.

NodeScalingOptions

Scaling options for nodes.

EdgeScalingOptions

Scaling options for edges.

ArrowStyle

Individual arrow style options.

SmoothOptions

Smooth options for edges.

ChosenNodeStyle

Style options for chosen (selected) nodes.

ChosenEdgeStyle

Style options for chosen (selected) edges.

ChosenLabelStyle

Style options for chosen (selected) labels.

ChosenNodeOptions

Options for chosen (selected) nodes.

ChosenEdgeOptions

Options for chosen (selected) edges.

NodeColorOptions

Color options for nodes.

NodeFontOptions

Font options for node labels.

ClusterDefinition

Definition for a predefined cluster.

ClusterNodeProperties

Properties for cluster nodes.

NodeOptions

Complete node styling and behavior options.

EdgeColorOptions

Color options for edges.

ArrowOptions

Arrow options for edges.

EdgeOptions

Complete edge styling and behavior options.

PhysicsStabilizationOptions

Physics stabilization options.

BarnesHutSolverOptions

Barnes Hut physics solver options.

ForceAtlasToBasedSolverOptions

Force Atlas 2 physics solver options.

RepulsionSolverOptions

Repulsion physics solver options.

HierarchicalRepulsionSolverOptions

Hierarchical Repulsion physics solver options.

PhysicsOptions

Physics simulation options.

KeyboardSpeedOptions

Keyboard speed options.

KeyboardOptions

Keyboard interaction options.

InteractionOptions

User interaction options.

HierarchicalLayoutOptions

Hierarchical layout options.

LayoutOptions

Layout configuration options.

Groups

Group definitions.

GroupOptions

Group options.

PredefinedClusterOptions

Options for predefined clustering behavior.

ExpandableClusteringOptions

Options for expandable clustering behavior.

ClusteringOptions

Comprehensive node clustering options.

ManipulationOptions

Optional GUI to alter the data in the network.

NetworkOptions

Complete network configuration options.

HybridServerBase

An application-agnostic http and websocket server.

GraphServer

A generic graph visualization server.

MultibodyGraphServer

Specialized GraphServer for SubGraph viewing.

Functions#

buildStandaloneHtml(→ str)

Generate an html file for offline graph viewing.

framesToGraph(...)

Convert a FrameContainer to a visjs NetworkGraph.

subGraphToGraph(...)

Convert a SubGraph to a visjs NetworkGraph.

multibodyConstraintEdges(...)

Create edges for all constraints in the provided SubGraph.

Package Contents#

class Karana.KUtils.visjs.Node#

Represents a node in the network graph.

id#

Unique ID for the node, automatically generated by default

Type:

int | str

label#

Text label displayed on the node

Type:

str

options#

Optional Node-specific styling and behavior options

Type:

NodeOptions | None

title#

Optional tooltip content (plain text or HTML)

Type:

str | None

cluster_group#

Optional cluster group name for expandable clustering (enables clustering when set)

Type:

str | None

id: int | str = ''#
label: str = ''#
options: NodeOptions | None = None#
title: str | None = None#
cluster_group: str | None = None#
__post_init__()[source]#

Validate tooltip behavior after initialization.

toDict() dict[str, JsonType][source]#

Convert node to dictionary for JSON serialization.

class Karana.KUtils.visjs.Edge#

Represents an edge between nodes in the network graph.

from_#

Source node ID

Type:

int | str

to#

Target node ID

Type:

int | str

id#

Unique ID for the edge, automatically generated by default

Type:

int | str

options#

Optional Edge-specific styling and behavior options

Type:

EdgeOptions | None

title#

Optional tooltip content (plain text or HTML)

Type:

str | None

from_: int | str#
to: int | str#
id: int | str = ''#
options: EdgeOptions | None = None#
title: str | None = None#
__post_init__()[source]#

Validate tooltip behavior after initialization.

toDict() dict[str, JsonType][source]#

Convert edge to dictionary for JSON serialization.

class Karana.KUtils.visjs.NetworkGraph#

Bases: ToDictMixin

Represents a graph with nodes, edges, and global options.

nodes#

Nodes in the graph. Default is empty list.

Type:

list[Node]

edges#

Edges connecting the nodes. Default is empty list.

Type:

list[Edge]

options#

Global options for the graph.

Type:

NetworkOptions

title#

Title for the graph. Default is “kdFlex Graph Visualization”

Type:

str

nodes: list[Node] = []#
edges: list[Edge] = []#
options: NetworkOptions#
title: str = 'kdFlex Graph Visualization'#
clone() Self[source]#

Get a deep copy.

__or__(other: Self) Self[source]#

Take the union of this graph and other.

Parameters:

other (Self) – The other graph to take the union with.

Returns:

A union of this graph and other.

Return type:

Self

__ior__(other: Self) Self[source]#

Take the union of this graph and other, but removes duplicates.

Parameters:

other (Self) – The other graph to union with.

Returns:

The union of this graph and other with duplicates removed.

Return type:

Self

removeIsolatedNodes()[source]#

Remove any nodes that aren’t touched by an edge.

class Karana.KUtils.visjs.Button#

Bases: ToDictMixin

Custom button to be displayed in the UI.

text#

The text displayed inside the button

Type:

str

callback#

No-argument, optionally async function called upon button press

Type:

Callable

id#

Unique id for the button, will be generated if omitted

Type:

str

style#

CSS styling for the button

Type:

dict[str, str]

type#

Context to show the button. Defaults to global.

Type:

Literal[“global”, “selected-node”, “selected-edge”]

Note#
Type:

style keys must be valid JavaScript identifiers. Use camelCase

where appropriate. See this MDN page for details
https#
Type:

//developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style

text: str#
callback: collections.abc.Callable#
id: str = ''#
style: dict[str, str]#
type: Literal['global', 'selected-node', 'selected-edge'] = 'global'#
class Karana.KUtils.visjs.FontStyleOptions#

Bases: ToDictMixin

Style options for font variants.

color: str | None = None#
size: int | None = None#
face: str | None = None#
mod: str | None = None#
class Karana.KUtils.visjs.FontOptions#

Bases: ToDictMixin

Font options for labels.

color: str | None = None#
size: int | None = None#
face: str | None = None#
background: str | None = None#
strokeWidth: int | None = None#
strokeColor: str | None = None#
align: str | None = None#
vadjust: int | None = None#
bold: FontStyleOptions | None = None#
ital: FontStyleOptions | None = None#
mono: FontStyleOptions | None = None#
multi: bool | None = None#
sizeMax: int | None = None#
class Karana.KUtils.visjs.ShadowOptions#

Bases: ToDictMixin

Shadow options for nodes and edges.

enabled: bool | None = None#
color: str | None = None#
size: int | None = None#
x: float | None = None#
y: float | None = None#
class Karana.KUtils.visjs.ShapeProperties#

Bases: ToDictMixin

Properties for custom node shapes.

borderDashes: list[int] | None = None#
borderRadius: int | None = None#
interpolation: bool | None = None#
class Karana.KUtils.visjs.WidthConstraintOptions#

Bases: ToDictMixin

Width constraint options for nodes.

minimum: int | None = None#
maximum: int | None = None#
class Karana.KUtils.visjs.NodeScalingOptions#

Bases: ToDictMixin

Scaling options for nodes.

min: int | None = None#
max: int | None = None#
label: FontOptions | None = None#
class Karana.KUtils.visjs.EdgeScalingOptions#

Bases: ToDictMixin

Scaling options for edges.

min: int | None = None#
max: int | None = None#
label: FontOptions | None = None#
class Karana.KUtils.visjs.ArrowStyle#

Bases: ToDictMixin

Individual arrow style options.

enabled: bool | None = None#
imageHeight: int | None = None#
imageWidth: int | None = None#
scaleFactor: float | None = None#
src: str | None = None#
class Karana.KUtils.visjs.SmoothOptions#

Bases: ToDictMixin

Smooth options for edges.

type: EdgeSmoothType | None = None#
forceDirection: str | None = None#
roundness: float | None = None#
class Karana.KUtils.visjs.ChosenNodeStyle#

Bases: ToDictMixin

Style options for chosen (selected) nodes.

borderWidth: int | None = None#
borderWidthSelected: int | None = None#
brokenImage: str | None = None#
color: str | None = None#
fontColor: str | None = None#
fontSize: int | None = None#
fontFace: str | None = None#
fontWeight: str | None = None#
icon: str | None = None#
iconFace: str | None = None#
iconSize: int | None = None#
iconWeight: str | None = None#
image: str | None = None#
image_padding: int | None = None#
label: str | None = None#
label_highlight_bold: bool | None = None#
level: int | None = None#
mass: float | None = None#
opacity: float | None = None#
physics: bool | None = None#
scaling: NodeScalingOptions | None = None#
shadow: ShadowOptions | None = None#
shape: str | None = None#
shapeProperties: ShapeProperties | None = None#
size: int | float | None = None#
title: str | None = None#
value: int | float | None = None#
widthConstraint: bool | int | WidthConstraintOptions | None = None#
x: float | None = None#
y: float | None = None#
class Karana.KUtils.visjs.ChosenEdgeStyle#

Bases: ToDictMixin

Style options for chosen (selected) edges.

arrows: str | ArrowStyle | None = None#
arrowStrikethrough: bool | None = None#
color: str | None = None#
dashes: bool | list[int] | None = None#
font: FontOptions | None = None#
hidden: bool | None = None#
hoverWidth: int | float | None = None#
label: str | None = None#
labelHighlightBold: bool | None = None#
length: float | None = None#
physics: bool | None = None#
scaling: EdgeScalingOptions | None = None#
selectionWidth: int | float | None = None#
selfReferenceSize: int | None = None#
shadow: ShadowOptions | None = None#
smooth: bool | str | SmoothOptions | None = None#
title: str | None = None#
width: int | float | None = None#
widthConstraint: bool | int | WidthConstraintOptions | None = None#
class Karana.KUtils.visjs.ChosenLabelStyle#

Bases: ToDictMixin

Style options for chosen (selected) labels.

color: str | None = None#
face: str | None = None#
size: int | None = None#
strokeWidth: int | None = None#
strokeColor: str | None = None#
align: str | None = None#
class Karana.KUtils.visjs.ChosenNodeOptions#

Bases: ToDictMixin

Options for chosen (selected) nodes.

node: ChosenNodeStyle | None = None#
label: ChosenLabelStyle | None = None#
class Karana.KUtils.visjs.ChosenEdgeOptions#

Bases: ToDictMixin

Options for chosen (selected) edges.

edge: ChosenEdgeStyle | None = None#
label: ChosenLabelStyle | None = None#
class Karana.KUtils.visjs.NodeColorOptions#

Bases: ToDictMixin

Color options for nodes.

border: str | None = None#
background: str | None = None#
highlight: dict[str, str] | None = None#
hover: dict[str, str] | None = None#
class Karana.KUtils.visjs.NodeFontOptions#

Bases: ToDictMixin

Font options for node labels.

color: str | None = None#
size: int | None = None#
face: str | None = None#
background: str | None = None#
strokeWidth: int | None = None#
strokeColor: str | None = None#
align: str | None = None#
vadjust: int | None = None#
multi: bool | None = None#
bold: FontStyleOptions | None = None#
ital: FontStyleOptions | None = None#
mono: FontStyleOptions | None = None#
class Karana.KUtils.visjs.ClusterDefinition#

Bases: ToDictMixin

Definition for a predefined cluster.

cluster_id: str#
label: str#
node_ids: list[str]#
color: str | None = None#
shape: str | None = None#
size: int | None = None#
group: str | None = None#
description: str | None = None#
class Karana.KUtils.visjs.ClusterNodeProperties#

Bases: ToDictMixin

Properties for cluster nodes.

allowSingleNodeCluster: bool | None = None#
clusterNodeProperties: dict[str, JsonType] | None = None#
class Karana.KUtils.visjs.NodeOptions#

Bases: ToDictMixin

Complete node styling and behavior options.

borderWidth: int | None = None#
borderWidthSelected: int | None = None#
brokenImage: str | None = None#
chosen: ChosenNodeOptions | None = None#
clusterNodeProperties: ClusterNodeProperties | None = None#
color: str | NodeColorOptions | None = None#
font: NodeFontOptions | None = None#
group: str | None = None#
hidden: bool | None = None#
icon: str | None = None#
iconFontFace: str | None = None#
iconSize: int | None = None#
image: str | None = None#
imagePadding: int | None = None#
label: str | None = None#
labelHighlightBold: bool | None = None#
level: int | None = None#
margin: dict[str, int] | None = None#
mass: float | None = None#
physics: bool | None = None#
scaling: NodeScalingOptions | None = None#
shadow: ShadowOptions | None = None#
shape: NodeShape | None = None#
shapeProperties: ShapeProperties | None = None#
size: int | float | None = None#
title: str | None = None#
value: int | float | None = None#
widthConstraint: bool | int | WidthConstraintOptions | None = None#
x: float | None = None#
y: float | None = None#
class Karana.KUtils.visjs.EdgeColorOptions#

Bases: ToDictMixin

Color options for edges.

color: str | None = None#
highlight: str | None = None#
hover: str | None = None#
inherit: bool | str | None = None#
opacity: float | None = None#
class Karana.KUtils.visjs.ArrowOptions#

Bases: ToDictMixin

Arrow options for edges.

to: ArrowStyle | None = None#
middle: ArrowStyle | None = None#
from_: ArrowStyle | None = None#
class Karana.KUtils.visjs.EdgeOptions#

Bases: ToDictMixin

Complete edge styling and behavior options.

arrows: str | ArrowOptions | None = None#
arrowStrikethrough: bool | None = None#
chosen: ChosenEdgeOptions | None = None#
color: str | EdgeColorOptions | None = None#
dashes: bool | list[int] | None = None#
font: FontOptions | None = None#
from_: str | int | None = None#
hidden: bool | None = None#
hoverWidth: int | float | None = None#
label: str | None = None#
label_highlight_bold: bool | None = None#
length: float | None = None#
physics: bool | None = None#
scaling: EdgeScalingOptions | None = None#
selectionWidth: int | float | None = None#
selfReferenceSize: int | None = None#
shadow: ShadowOptions | None = None#
smooth: bool | SmoothOptions | None = None#
title: str | None = None#
to: str | int | None = None#
value: int | float | None = None#
width: int | float | None = None#
widthConstraint: bool | int | WidthConstraintOptions | None = None#
class Karana.KUtils.visjs.PhysicsStabilizationOptions#

Bases: ToDictMixin

Physics stabilization options.

enabled: bool | None = None#
iterations: int | None = None#
updateInterval: int | None = None#
onlyDynamicEdges: bool | None = None#
fit: bool | None = None#
class Karana.KUtils.visjs.BarnesHutSolverOptions#

Bases: ToDictMixin

Barnes Hut physics solver options.

theta: float | None = None#
gravitationalConstant: float | None = None#
centralGravity: float | None = None#
springLength: float | None = None#
springConstant: float | None = None#
damping: float | None = None#
avoidOverlap: float | None = None#
class Karana.KUtils.visjs.ForceAtlasToBasedSolverOptions#

Bases: ToDictMixin

Force Atlas 2 physics solver options.

theta: float | None = None#
gravitationalConstant: float | None = None#
centralGravity: float | None = None#
springLength: float | None = None#
springConstant: float | None = None#
damping: float | None = None#
avoidOverlap: float | None = None#
class Karana.KUtils.visjs.RepulsionSolverOptions#

Bases: ToDictMixin

Repulsion physics solver options.

nodeDistance: float | None = None#
centralGravity: float | None = None#
springLength: float | None = None#
springConstant: float | None = None#
damping: float | None = None#
class Karana.KUtils.visjs.HierarchicalRepulsionSolverOptions#

Bases: ToDictMixin

Hierarchical Repulsion physics solver options.

nodeDistance: float | None = None#
centralGravity: float | None = None#
springLength: float | None = None#
springConstant: float | None = None#
damping: float | None = None#
avoidOverlap: float | None = None#
class Karana.KUtils.visjs.PhysicsOptions#

Bases: ToDictMixin

Physics simulation options.

enabled: bool | None = None#
timestep: float | None = None#
adaptiveTimestep: bool | None = None#
maxVelocity: float | None = None#
minVelocity: float | None = None#
stabilization: PhysicsStabilizationOptions | None = None#
solver: PhysicsSolver | None = None#
barnesHut: BarnesHutSolverOptions | None = None#
forceAtlasToBased: ForceAtlasToBasedSolverOptions | None = None#
repulsion: RepulsionSolverOptions | None = None#
hierarchicalRepulsion: HierarchicalRepulsionSolverOptions | None = None#
class Karana.KUtils.visjs.KeyboardSpeedOptions#

Bases: ToDictMixin

Keyboard speed options.

x: float | None = None#
y: float | None = None#
class Karana.KUtils.visjs.KeyboardOptions#

Bases: ToDictMixin

Keyboard interaction options.

enabled: bool | None = None#
speed: KeyboardSpeedOptions | None = None#
bindToWindow: bool | None = None#
class Karana.KUtils.visjs.InteractionOptions#

Bases: ToDictMixin

User interaction options.

dragNodes: bool | None = None#
dragView: bool | None = None#
hideEdgesOnDrag: bool | None = None#
hideEdgesOnZoom: bool | None = None#
hideNodesOnDrag: bool | None = None#
hover: bool | None = None#
hoverConnectedEdges: bool | None = None#
keyboard: bool | KeyboardOptions | None = None#
multiselect: bool | None = None#
navigationButtons: bool | None = None#
selectConnectedEdges: bool | None = None#
tooltipDelay: int | None = None#
zoomSpeed: float | None = None#
zoomView: bool | None = None#
class Karana.KUtils.visjs.HierarchicalLayoutOptions#

Bases: ToDictMixin

Hierarchical layout options.

enabled: bool = False#
levelSeparation: float = 150#
nodeSpacing: float = 100#
treeSpacing: float = 200#
blockShifting: bool = True#
edgeMinimization: bool = True#
parentCentralization: bool = True#
direction: HierarchicalDirection = 'UD'#
sortMethod: HierarchicalSortMethod = 'hubsize'#
class Karana.KUtils.visjs.LayoutOptions#

Bases: ToDictMixin

Layout configuration options.

improvedLayout: bool = True#
hierarchical: HierarchicalLayoutOptions | None = None#
class Karana.KUtils.visjs.Groups#

Bases: ToDictMixin

Group definitions.

class Karana.KUtils.visjs.GroupOptions#

Bases: ToDictMixin

Group options.

useDefaultGroups: bool | None = None#
groups: Groups | None = None#
class Karana.KUtils.visjs.PredefinedClusterOptions#

Bases: ToDictMixin

Options for predefined clustering behavior.

auto_cluster_on_load: bool = True#
preserve_cluster_state: bool = True#
cluster_by_group: bool = True#
min_nodes_for_cluster: int = 2#
cluster_shape: NodeShape = 'ellipse'#
cluster_border_width: int = 3#
show_cluster_count: bool = True#
class Karana.KUtils.visjs.ExpandableClusteringOptions#

Bases: ToDictMixin

Options for expandable clustering behavior.

enabled: bool = True#
auto_detect_groups: bool = True#
min_nodes_for_cluster: int = 2#
cluster_shape: NodeShape = 'ellipse'#
cluster_size: int = 40#
cluster_border_width: int = 3#
cluster_font_size: int = 14#
cluster_font_color: str = '#FFFFFF'#
show_cluster_count: bool = True#
preserve_edge_connections: bool = True#
enable_double_click_expand: bool = True#
enable_buttons: bool = True#
color_scheme: dict[str, str] = None#
__post_init__()[source]#

Set default color scheme if not provided.

class Karana.KUtils.visjs.ClusteringOptions#

Bases: ToDictMixin

Comprehensive node clustering options.

enabled: bool | None = None#
predefined_clusters: list[ClusterDefinition] | None = None#
predefined_options: PredefinedClusterOptions | None = None#
expandable: ExpandableClusteringOptions | None = None#
default_cluster_color: str = '#95A5A6'#
preserve_original_properties: bool = True#
class Karana.KUtils.visjs.ManipulationOptions#

Bases: ToDictMixin

Optional GUI to alter the data in the network.

Leave a value as None to use the vis.js default.

Details at:

https://visjs.github.io/vis-network/docs/network/manipulation.html

enabled: bool | None = None#
class Karana.KUtils.visjs.NetworkOptions#

Bases: ToDictMixin

Complete network configuration options.

nodes: NodeOptions | None = None#
edges: EdgeOptions | None = None#
physics: PhysicsOptions | None = None#
layout: LayoutOptions | None = None#
interaction: InteractionOptions | None = None#
groups: GroupOptions | None = None#
configure: ConfigureOptions | None = None#
clustering: ClusteringOptions | None = None#
manipulation: ManipulationOptions | None = None#
__post_init__()[source]#

Set default values after initialization.

class Karana.KUtils.visjs.HybridServerBase(*, host: str | None = None, port: int = 8000, autorun: bool = True, static_path: pathlib.Path | None = None, log_level: str = 'warning')#

Bases: abc.ABC

An application-agnostic http and websocket server.

This class lets the user register http request handlers at arbitrary URLs. Additionally, requests at the /ws URL are automatically upgraded to a persistent websocket connection. This allows the server to send messages to clients without waiting for an http request from the client. The server will also automatically serve a directory of static files, specified by the static_path constructor argument. These are served relative to the /static URL. This class is built on top of fastapi and uvicorn but takes care of the details of running the server in an async loop on a background.

This class is abstract, so to use it, one must define a subclass that implements the missing methods even if the implementations do nothing. These include:

  • onConnect: called when a websocket connection is created

  • onMessage: called when receiving a websocket message

  • onDisconnect: called when a websocket connection closes

Additionally, one may override the setupRoutes method to register additional http request handlers. If overriding this method it’s recommended to call super().setupRoutes() to still setup the basic handlers created by this class.

user_port = 8000#
static_path = None#
log_level = 'warning'#
server_error = None#
app#
thread = None#
clients#
loop = None#
server = None#
property started: bool#

Whether the server has started.

There are really three possible states: not started, starting but not ready, and ready. To simplify logic and avoid race conditions, if the server is starting but not fully ready this will block until the server is fully ready then return True.

Returns:

Whether the server is started and ready to use

Return type:

bool

run()[source]#

Idempotently start the server on a background thread.

close(timeout: int | float = 5)[source]#

Idempotently shutdown the server and all connections.

Parameters:

timeout (int | float) – Maximum wait time in seconds for the server thread to stop

__del__()[source]#

Ensure the server is shutdown upon going out of scope.

broadcast(message: str)[source]#

Send a message to all connected clients.

May be called from any thread.

abstract onConnect(websocket: fastapi.WebSocket)[source]#
Async:

When a new websocket client connects, this method is called.

This must be overridden with the desired behavior, even if that’s a no-op.

abstract onMessage(websocket: fastapi.WebSocket, message: str)[source]#
Async:

When a message is received from a websocket client, this method is called.

This must be overridden with the desired behavior, even if that’s a no-op.

abstract onDisconnect(websocket: fastapi.WebSocket)[source]#
Async:

When a websocket client disconnects, this method is called.

This must be overridden with the desired behavior, even if that’s a no-op.

setupRoutes()[source]#

Set up the API endpoints including the websocket handler.

This base implementation adds the following routes:

  • /ws: upgrade into a websocket connection

  • /static/*: recursively serve files in self.static_path if not None

  • /: if serving a file at /static/index.html also serve it here

  • /health: respond with 200 OK. This gives clients a lightweight method of checking whether the server is up.

This may be overridden to add more routes, but in this case it is recommended to call super().setupRoutes() so that the basic routes added by this class are preserved.

property port: int#

Get the server’s port.

Usually this is whatever was passed to the constructor, but for port=0 this will be replaced with the actual port number after the server is started.

Returns:

The port number

Return type:

int

property url: str#

Get the base URL of the server.

This includes the protocol, address, and port number. Note that this is merely a best guess and may be inaccurate, for instance if accessing the server via a proxy.

Returns:

The server’s base url

Return type:

str

block(prompt: str = 'Press Ctrl-C to shutdown the server')[source]#

Block the thread from which this is called.

This is mainly intended as a way to keep the server alive when the main thread is about to exit.

Parameters:

prompt (str) – The message to print before blocking

launchLocalClient()[source]#

Open a browser tab at the server’s URL.

printConnectionInfo()[source]#

Print a message about how to connect to the server.

Karana.KUtils.visjs.buildStandaloneHtml(graph: Karana.KUtils.visjs._datatypes.NetworkGraph) str#

Generate an html file for offline graph viewing.

Given a NetworkGraph, this generates the contents a complete, self-contained HTML file showing the graph with vis.js. The HTML bundles all required information including the vis.js library, so it can be saved to a file and later viewed offline in a web browser.

Parameters:

graph (NetworkGraph) – The graph to visualize

Returns:

The contents of the standalone html file

Return type:

str

class Karana.KUtils.visjs.GraphServer(graph: Karana.KUtils.visjs._datatypes.NetworkGraph | None = None, *, port=8765, autorun: bool = True, log_level: str = 'warning', buttons: list[Karana.KUtils.visjs._datatypes.Button] | None = None)#

Bases: Karana.KUtils.visjs._baseserver.HybridServerBase

A generic graph visualization server.

This builds on HybridServerBase and uses the vis.js library to provide a server for visualizing and interacting with graph topologies in the web browser. The server can be specialized with frontend buttons and event handlers that trigger server-side callbacks. Additionally the server can broadcast to clients changes to the graph topology and appearance via a live websocket connection.

graph#
buttons#
setupRoutes()[source]#

Add http request handlers.

In additional to everything added in HybridServerBase.setupRoutes, this adds the /standalone.html route, which serves a fully self-contained html file showing the graph. This file can be saved and later reopened in a web browser for offline viewing.

This may be overridden to add more routes, but in this case it is recommended to call super().setupRoutes() so that the routes added by this class are preserved.

launchLocalClient(standalone: bool = False)[source]#

Open a client in a browser tab local to the server.

Parameters:

standalone (bool) – If True, instead open the /standalone.html URL, which serves a self-contained HTML file that is missing some features but can be saved and later opened for offline viewing. Defaults to False.

updateClientGraphs()[source]#

Update clients to use the current graph.

This must be called after modifying or replacing self.graph for the modifications to show up in connected clients.

addButton(button: Karana.KUtils.visjs._datatypes.Button)[source]#

Add a button to current and future frontends.

Parameters:

button (Button) – Description of the button, including a server-side callback

async onConnect(websocket: fastapi.WebSocket)[source]#

Handle a new client connecting.

We initialize the graph and UI elements of the new client.

Parameters:

websocket (WebSocket) – The websocket client which just connected

async onMessage(websocket: fastapi.WebSocket, message: str)[source]#

Handle receiving a websocket client message.

Based on the message type we delegate to the appropriate handler method.

Parameters:
  • websocket (WebSocket) – The websocket client which sent the message

  • message (str) – The message text as a plain unparsed string

async onDisconnect(websocket: fastapi.WebSocket)[source]#

Handle a websocket client disconnecting.

There’s nothing extra we need to do so this is a no-op.

Parameters:

websocket (WebSocket) – The websocket client which just disconnected

async onClickNode(websocket: fastapi.WebSocket, node_id: int | str)[source]#

When a user clicks on a node, this method is called.

Parameters:
  • websocket (WebSocket) – The associated websocket.

  • node_id (int | str) – The node clicked on.

async onClickEdge(websocket: fastapi.WebSocket, edge_id: int | str)[source]#

When a user clicks on an edge, this method is called.

Parameters:
  • websocket (WebSocket) – The associated websocket.

  • edge_id (int | str) – The edge clicked on.

Karana.KUtils.visjs.framesToGraph(frames: Karana.Frame.FrameContainer, *, title='Frame layer', label_map: dict[int | str, str] | None = None, coloring: Literal['type', 'valency'] = 'type', chains: bool = False) Karana.KUtils.visjs._datatypes.NetworkGraph#

Convert a FrameContainer to a visjs NetworkGraph.

Parameters:
  • frames (FrameContainer) – Source of frames to show.

  • title (str) – Title of the graph, defaults to “Frame layer”

  • label_map (dict[int | str, str] | None) – Optional map to look up string labels for frames. Keys may be either frame ids or frame names.

  • coloring (Literal["type", "valency"]) –

    How to color the nodes and edges in the visualization:

    type: Color based on the type of the Frame or FrameToFrame valency: Color nodes based on number of connecting edges

    Defaults to the “type” coloring.

  • chains (bool) – Whether to show edges for ChainedFrameToFrames. Defaults to False.

Returns:

The NetworkGraph for the FrameContainer, ready for visualization

Return type:

NetworkGraph

Karana.KUtils.visjs.subGraphToGraph(subgraph: Karana.Dynamics.SubGraph, title='Multibody System', label_map: dict[int | str, str] | None = None, constraints: bool = True) Karana.KUtils.visjs._datatypes.NetworkGraph#

Convert a SubGraph to a visjs NetworkGraph.

Parameters:
  • subgraph (SubGraph) – The subgraph object to show

  • title (str) – Title of the graph, defaults to “Multibody System”

  • label_map (dict[int | str, str] | None) – Optional map to look up string labels for bodies. Keys may be either body ids or body names.

  • constraints (bool) – Whether to created edges for constraints; True by default

Returns:

The NetworkGraph for the SubGraph, ready for visualization

Return type:

NetworkGraph

Karana.KUtils.visjs.multibodyConstraintEdges(subgraph: Karana.Dynamics.SubGraph) list[Karana.KUtils.visjs._datatypes.Edge]#

Create edges for all constraints in the provided SubGraph.

Parameters:

subgraph (SubGraph) – The SubGraph whose constraints will be used to create edges.

Returns:

A list of edges, where every edge is associated with a constraint in the provided SubGraph.

Return type:

list[Edge]

class Karana.KUtils.visjs.MultibodyGraphServer(subgraph: Karana.Dynamics.SubGraph, *, title='Multibody System', port=8765, autorun: bool = True, log_level: str = 'warning', buttons: list[Karana.KUtils.visjs._datatypes.Button] | None = None, label_map: dict[int | str, str] | None = None, extra_edges: dict[str, list[Karana.KUtils.visjs._datatypes.Edge]] | list[Karana.KUtils.visjs._datatypes.Edge] | None = None)#

Bases: Karana.KUtils.visjs._server.GraphServer

Specialized GraphServer for SubGraph viewing.

Given a SubGraph, this automatically generates a set of graphs with and without constraints and other sets of extra edges. Buttons are automatically added to toggle different parts of the graph on and off.

subgraphs#
enableSubGraph(label: str)[source]#

Enable the SubGraph with the given label.

Parameters:

label (str) – The SubGraph to enable.

disableSubGraph(label: str)[source]#

Disable the SubGraph with the given label.

Parameters:

label (str) – The SubGraph to disable.