Live Visualisation of the IOTA Tangle using a dynamically layouted graph. Demo: http://tangle.glumb.de
All circles represent transactions (tx) in the IOTA Tangle. A circular buffer is used to populate the viewer with the last 1800 (configurable) tx on page load.
Hover a tx to see more details:
- bottom left: value, tag, hash
- top left: how many tx are confirming the selcted one (yellow)
- top left: how many tx are confirmed by the selcted one (magenta)
- tx of the same bundle are highlightes in blue
Use the input boxes on the left to filter by hast, tag or bundle. The tag filter is applied using a regex.
Toggle switches on the top right:
| config | description |
|---|---|
| remove floating tx | some tx are not visually attached to the tangle since their attachement point lays so far back that it is not displayed anymore. Automatic removal of those tx increases performance |
| limit to 4k tx | for continuous use only 4000 tx are kept on screen. Older tx are deleted first. |
| pin old tx | pinning old tx increases performance by disabling their physics ad thus excluding them from the layouting process |
| reduce moevement | spawns new nodes close to their neighbours |
| size by # of confirms | tx that have been confirmed by more tx have a bigger diameter |
| size by weight | tx that confirm more tx have a bigger diameter |
| size by value | size based on transferred iota value |
| color by order | color ty based on the order they appear on screen. Continuous hue rotation |
In adition to setting configuration parameters using the ui, URL parameters can be used for presets.
Example:
http://tangle.glumb.de/?DARK_MODE=true&CIRCLE_SIZE=40&HIGHLIGHT_COLOR_FORWARD="0xbada55ff"&svg
Syntax
http://tangle.glumb.de/?<CONFIG_PARAM_NAME>=<VALUE>[&<CONFIG_PARAM_NAME>=<VALUE>]
Available Configuration Parameters
CIRCLE_SIZE: 30, // size of a node REMOVE_LONLY_AFTER_S: 30, // remove floating nodes after time REMOVE_SMALLER_THAN_PERCENTAGE_OF_TOTAL_MESH: 0.03, // remove graphs that are smaller than % of all nodes MAX_CIRCLE_SIZE: 80, // max node size used e.g. for 'size by value' MAX_NODES: 4000, // max nodes when 'limit to 4k nodes' is enabled // options REMOVE_FLOATING_NODES: true, COLOR_BY_DEPTH: false, SIZE_BY_VALUE: false, // size based on transferred iota value SIZE_BY_WEIGHT: false, // tx that confirm more tx have a bigger diameter REMOVE_OLD_NODES: false, // only MAX_NODES tx are kept on screen. Older tx are deleted first. PIN_OLD_NODES: true, // pinning old tx increases performance by disabling their physics ad thus excluding them from the layouting process LIGHT_LINKS: false, SPAWN_NODE_NEAR_FINAL_POSITION: true, // spawns new nodes close to their neighbours COLOR_BY_NUMBER: false, // color ty based on the order they appear on screen. Continuous hue rotation DARK_MODE: false, // colors HIGHLIGHT_MULTIPLE_COLOR: 0xda4b29, // for tags, hash, bundle filter SAME_BUNDLE_COLOR: 0x1287ff, LIGHT_LINK_COLOR: 0x222222ff, LIGHT_NODE_COLOR: 0x000000ff, LIGHT_NODE_BG_COLOR: 0xffffff, NODE_CONFIRMED_COLOR: 0x000000, HIGHLIGHT_COLOR_FORWARD: 0xf1b727ff, HIGHLIGHT_COLOR_BACKWARD: 0xe23df4ff, NODE_MILESTONE_COLOR: 0xe53d6f, NODE_TIP_COLOR: 0x1fe0be, LINK_COLOR: 0, NODE_COLOR: 0, NODE_BG_COLOR: 0, // sizes NODE_CONFIRMED_BORDER_SIZE: 1, NODE_BASE_BORDER_SIZE: 0.8, NODE_MILESTONE_BORDER_SIZE: 0.6, NODE_TIP_BORDER_SIZE: 0.6, // other TITLE: "The Tangle", EXPLORER_TX_LINK: "https://thetangle.org/transaction/", EXPLORER_BUNDLE_LINK: "https://thetangle.org/bundle/",
Additional Parameters
Use hash=<tx-hash>, bundle=<bundle-hash>, tag=<tx-tag> to select a tx. Use with caution. The tx is only highlighted when on screen. Older tx are not queried.
Use svg=true to display a svg export utility button on the top left.
Clone the repo and run npm install.
The visualiser can be used for multiple networks (Mainnet, testnet, Customnet). The main entrypoint is the <NAME>App.js file.
To get started open the mainnetApp.js and configure the ZMQ_ENDPOINT and LSM_NODE.
Run node mainnnetApp.js to start the server. Done :)
To add another network, copy the mainnetApp.js and rename it to <CustomName>App.js. Copy the mainnetdata.json and also rename it to <CustomName>data.json.
Set your network endpoints in <CustomName>App.js and also set the NAME to <CustomName>.
The visualiser follows simple client server architecture. Server-side a ZMQ client is used for for data aquisition. It listens to the ZMQ Transaction stream of an IOTA Fullnode. An Instance of the IOTA JS library is used to peridically poll the latest milestone index.
Transactions are stroed in a ringbuffer to send the last 1800TX to the client on pageload.
IOTA Tangle Glumb Architecture
The data send to the client via WebSocket follow this structure:
TX - Transaction
{ hash, address, value, tag, timestamp, current_index, last_index, bundle_hash, transaction_trunk, transaction_branch; }
SN - Confirmed Transaction
{ hash, address, transaction_trunk, transaction_branch, bundle; }
The clients data interface is based on the SocketIO library. Therefore it is server agnostic as along as the expected SocketIO events are emittet by the backend.
On initialisation/pageload the following events are expected:
socket.emit("config", FRONTEND_CONFIG); // { networkName } socket.emit("inittx", txArray); // see format above socket.emit("initsn", snArray); // see format above socket.emit("initms", mileStoneArray); // Array of milestone tx hashes
During runtime the following event can be fired:
socket.emit("tx", tx); // see format above socket.emit("sn", sn); // see format above socket.emit("ms", ms); // milestone tx hash
include th following scripts
<link rel="stylesheet" href="main.css" /> <script src="lib/vivagraph.js"></script> <script src="main.js"></script> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" crossorigin="anonymous" ></script>
Instantiate TangleGlumb($DOMElement, [config])
const tg = TangleGlumb(document.getElementById("graph"), { CIRCLE_SIZE: 60, PIN_OLD_NODES: false, STATIC_FRONT: false }); tg.updateTx([tx]); tg.removeTx([tx]);
Add and update array of transactions using TG.updateTx(Array<txObj>)
const tx = { hash: "", address: "", value: 0, timestamp: Date.now(), bundle_hash: "", transaction_branch: "", transaction_trunk: "", tag: "" milestone: false, //optional confirmed: false, //optional }; tg.updateTx([tx]);
Remove transactions from the visualisation using TG.removeTx(Array<txObj|hash>)
const tx = { hash: "", address: "", value: 0, timestamp: Date.now(), bundle_hash: "", transaction_branch: "", transaction_trunk: "", tag: "" milestone: false, //optional confirmed: false, //optional }; tg.removeTx([tx, tx.hash]);